mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-07-30 14:47:53 +00:00
porting: Add FreeRTOS port (based on nRF5 SDK)
This patch adds port of Nimble stack to FreeRTOS based on nRF5 SDK. It's split into 'common' part which can be used a base for porting to any other platform and 'freertos_nrf5_sdk' which has FreeRTOS-specific files and makefile. Building and flashing is similar to other demo apps from nRF5 SDK: $ make -C porting/freertos_nrf5_sdk The resulting image can be flashed on nRF52 DK: $ make -C porting/freertos_nrf5_sdk flash Location of nRF5 SDK is set by NRF5_SDK_ROOT variable. By default it is set to 'nrf5_sdk' subdirectory so a symlink would work just fine: $ ln -s <x>/nRF5_SDK_12.3.0_d7731ad porting/freertos_nrf5_sdk/nrf5_sdk
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
# note: no / at the end since it could be either symlink or directory
|
||||
/porting/freertos_nrf5_sdk/nrf5_sdk
|
||||
/porting/freertos_nrf5_sdk/_build/
|
||||
@@ -0,0 +1,14 @@
|
||||
#ifndef H_BSP_H
|
||||
#define H_BSP_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define bssnz_t
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_BSP_H */
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __CONSOLE_H__
|
||||
#define __CONSOLE_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_eventq;
|
||||
|
||||
struct console_input {
|
||||
char line[0];
|
||||
};
|
||||
|
||||
typedef void (*console_rx_cb)(void);
|
||||
typedef int (*console_append_char_cb)(char *line, uint8_t byte);
|
||||
typedef void (*completion_cb)(char *str, console_append_char_cb cb);
|
||||
|
||||
static int inline
|
||||
console_is_init(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inline
|
||||
console_init(console_rx_cb rx_cb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inline
|
||||
console_write(const char *str, int cnt)
|
||||
{
|
||||
}
|
||||
|
||||
static int inline
|
||||
console_read(char *str, int cnt, int *newline)
|
||||
{
|
||||
*newline = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inline
|
||||
console_blocking_mode(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void inline
|
||||
console_non_blocking_mode(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void inline
|
||||
console_echo(int on)
|
||||
{
|
||||
}
|
||||
|
||||
static int inline console_printf(const char *fmt, ...)
|
||||
__attribute__ ((format (printf, 1, 2)));
|
||||
|
||||
static int inline
|
||||
console_printf(const char *fmt, ...)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void inline
|
||||
console_set_queues(struct os_eventq *avail_queue,
|
||||
struct os_eventq *cmd_queue)
|
||||
{
|
||||
}
|
||||
|
||||
static void inline
|
||||
console_set_completion_cb(void (*completion)(char *str, console_append_char_cb cb))
|
||||
{
|
||||
}
|
||||
|
||||
static int inline
|
||||
console_handle_char(uint8_t byte)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int inline
|
||||
console_out(int character)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define console_is_midline (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CONSOLE__ */
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_HAL_TIMER_
|
||||
#define H_HAL_TIMER_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "os/queue.h"
|
||||
|
||||
/* HAL timer struct */
|
||||
typedef void (*hal_timer_cb)(void *arg);
|
||||
|
||||
/**
|
||||
* The HAL timer structure. The user can declare as many of these structures
|
||||
* as desired. They are enqueued on a particular HW timer queue when the user
|
||||
* calls the hal_timer_start or hal_timer_start_at API. The user must have
|
||||
* called hal_timer_set_cb before starting a timer.
|
||||
*
|
||||
* NOTE: the user should not have to modify/examine the contents of this
|
||||
* structure; the hal timer API should be used.
|
||||
*/
|
||||
struct hal_timer
|
||||
{
|
||||
void *bsp_timer; /* Internal platform specific pointer */
|
||||
hal_timer_cb cb_func; /* Callback function */
|
||||
void *cb_arg; /* Callback argument */
|
||||
uint32_t expiry; /* Tick at which timer should expire */
|
||||
TAILQ_ENTRY(hal_timer) link; /* Queue linked list structure */
|
||||
};
|
||||
|
||||
/* Initialize a HW timer. */
|
||||
int hal_timer_init(int timer_num, void *cfg);
|
||||
|
||||
/* Un-initialize a HW timer. */
|
||||
int hal_timer_deinit(int timer_num);
|
||||
|
||||
/*
|
||||
* Config a HW timer at the given frequency and start it. If the exact
|
||||
* frequency is not obtainable the closest obtainable frequency is set.
|
||||
*/
|
||||
int hal_timer_config(int timer_num, uint32_t freq_hz);
|
||||
|
||||
/*
|
||||
* Returns the resolution of the HW timer. NOTE: the frequency may not be
|
||||
* obtainable so the caller can use this to determine the resolution.
|
||||
* Returns resolution in nanoseconds. A return value of 0 indicates an invalid
|
||||
* timer was used.
|
||||
*/
|
||||
uint32_t hal_timer_get_resolution(int timer_num);
|
||||
|
||||
/* Returns the HW timer current tick value */
|
||||
uint32_t hal_timer_read(int timer_num);
|
||||
|
||||
/* Perform a blocking delay for a number of ticks. */
|
||||
int hal_timer_delay(int timer_num, uint32_t ticks);
|
||||
|
||||
/*
|
||||
* Set the timer structure prior to use. Should not be called if the timer
|
||||
* is running. Must be called at least once prior to using timer.
|
||||
*/
|
||||
int hal_timer_set_cb(int timer_num, struct hal_timer *tmr, hal_timer_cb cb_func,
|
||||
void *arg);
|
||||
|
||||
/* Start a timer that will expire in 'ticks' ticks. Ticks cannot be 0 */
|
||||
int hal_timer_start(struct hal_timer *, uint32_t ticks);
|
||||
|
||||
/*
|
||||
* Start a timer that will expire when the timer reaches 'tick'. If tick
|
||||
* has already passed the timer callback will be called "immediately" (at
|
||||
* interrupt context).
|
||||
*/
|
||||
int hal_timer_start_at(struct hal_timer *, uint32_t tick);
|
||||
|
||||
/* Stop a currently running timer; associated callback will NOT be called */
|
||||
int hal_timer_stop(struct hal_timer *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_HAL_TIMER_ */
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_IGNORE_
|
||||
#define H_IGNORE_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* These macros prevent the "set but not used" warnings for log writes below
|
||||
* the log level.
|
||||
*/
|
||||
|
||||
#define IGN_1(X) ((void)(X))
|
||||
#define IGN_2(X, ...) ((void)(X));IGN_1(__VA_ARGS__)
|
||||
#define IGN_3(X, ...) ((void)(X));IGN_2(__VA_ARGS__)
|
||||
#define IGN_4(X, ...) ((void)(X));IGN_3(__VA_ARGS__)
|
||||
#define IGN_5(X, ...) ((void)(X));IGN_4(__VA_ARGS__)
|
||||
#define IGN_6(X, ...) ((void)(X));IGN_5(__VA_ARGS__)
|
||||
#define IGN_7(X, ...) ((void)(X));IGN_6(__VA_ARGS__)
|
||||
#define IGN_8(X, ...) ((void)(X));IGN_7(__VA_ARGS__)
|
||||
#define IGN_9(X, ...) ((void)(X));IGN_8(__VA_ARGS__)
|
||||
#define IGN_10(X, ...) ((void)(X));IGN_9(__VA_ARGS__)
|
||||
#define IGN_11(X, ...) ((void)(X));IGN_10(__VA_ARGS__)
|
||||
#define IGN_12(X, ...) ((void)(X));IGN_11(__VA_ARGS__)
|
||||
#define IGN_13(X, ...) ((void)(X));IGN_12(__VA_ARGS__)
|
||||
#define IGN_14(X, ...) ((void)(X));IGN_13(__VA_ARGS__)
|
||||
#define IGN_15(X, ...) ((void)(X));IGN_14(__VA_ARGS__)
|
||||
#define IGN_16(X, ...) ((void)(X));IGN_15(__VA_ARGS__)
|
||||
#define IGN_17(X, ...) ((void)(X));IGN_16(__VA_ARGS__)
|
||||
#define IGN_18(X, ...) ((void)(X));IGN_17(__VA_ARGS__)
|
||||
#define IGN_19(X, ...) ((void)(X));IGN_18(__VA_ARGS__)
|
||||
#define IGN_20(X, ...) ((void)(X));IGN_19(__VA_ARGS__)
|
||||
|
||||
#define GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, \
|
||||
_13, _14, _15, _16, _17, _18, _19, _20, NAME, ...) NAME
|
||||
#define IGNORE(...) \
|
||||
GET_MACRO(__VA_ARGS__, IGN_20, IGN_19, IGN_18, IGN_17, IGN_16, IGN_15, \
|
||||
IGN_14, IGN_13, IGN_12, IGN_11, IGN_10, IGN_9, IGN_8, IGN_7, \
|
||||
IGN_6, IGN_5, IGN_4, IGN_3, IGN_2, IGN_1)(__VA_ARGS__)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __SYS_LOG_STUB_H__
|
||||
#define __SYS_LOG_STUB_H__
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "log/ignore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LOG_DEBUG(__l, __mod, ...) IGNORE(__VA_ARGS__)
|
||||
#define LOG_INFO(__l, __mod, ...) IGNORE(__VA_ARGS__)
|
||||
#define LOG_WARN(__l, __mod, ...) IGNORE(__VA_ARGS__)
|
||||
#define LOG_ERROR(__l, __mod, ...) IGNORE(__VA_ARGS__)
|
||||
#define LOG_CRITICAL(__l, __mod, ...) IGNORE(__VA_ARGS__)
|
||||
|
||||
#define LOG_LEVEL_DEBUG 0
|
||||
#define LOG_LEVEL_INFO 1
|
||||
#define LOG_LEVEL_WARN 2
|
||||
#define LOG_LEVEL_ERROR 3
|
||||
#define LOG_LEVEL_CRITICAL 4
|
||||
/* Up to 7 custom log levels. */
|
||||
#define LOG_LEVEL_MAX UINT8_MAX
|
||||
#define LOG_SYSLEVEL UINT8_MAX
|
||||
|
||||
/* Logging medium */
|
||||
#define LOG_STORE_CONSOLE 1
|
||||
#define LOG_STORE_CBMEM 2
|
||||
#define LOG_STORE_FCB 3
|
||||
|
||||
/* Global log info */
|
||||
struct log_info {
|
||||
uint32_t li_next_index;
|
||||
uint8_t li_version;
|
||||
};
|
||||
|
||||
struct log_info g_log_info;
|
||||
|
||||
struct log {
|
||||
};
|
||||
|
||||
struct log_handler {
|
||||
};
|
||||
|
||||
static inline int
|
||||
log_register(char *name, struct log *log, const struct log_handler *h,
|
||||
void *arg, uint8_t level)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void
|
||||
log_init(void)
|
||||
{
|
||||
}
|
||||
|
||||
#define log_printf(...)
|
||||
|
||||
/*
|
||||
* Dummy handler exports.
|
||||
*/
|
||||
const struct log_handler log_console_handler;
|
||||
const struct log_handler log_cbmem_handler;
|
||||
const struct log_handler log_fcb_handler;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYS_LOG_STUB_H__ */
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_UTIL_MEM_
|
||||
#define H_UTIL_MEM_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_mempool;
|
||||
struct os_mbuf_pool;
|
||||
|
||||
int mem_malloc_mempool(struct os_mempool *mempool, int num_blocks,
|
||||
int block_size, char *name, void **out_buf);
|
||||
|
||||
int mem_malloc_mbuf_pool(struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool, int num_blocks,
|
||||
int block_size, char *name,
|
||||
void **out_buf);
|
||||
int mem_malloc_mbufpkt_pool(struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool, int num_blocks,
|
||||
int block_size, char *name,
|
||||
void **out_buf);
|
||||
int mem_init_mbuf_pool(void *mem, struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool, int num_blocks,
|
||||
int block_size, char *name);
|
||||
|
||||
/**
|
||||
* Specifies a function used as a callback. Functions of this type allocate an
|
||||
* mbuf chain meant to hold a packet fragment. The resulting mbuf must contain
|
||||
* a pkthdr.
|
||||
*
|
||||
* @param frag_size The number of data bytes that the mbuf will
|
||||
* eventually contain.
|
||||
* @param arg A generic parameter.
|
||||
*
|
||||
* @return An allocated mbuf chain on success;
|
||||
* NULL on failure.
|
||||
*/
|
||||
typedef struct os_mbuf *mem_frag_alloc_fn(uint16_t frag_size, void *arg);
|
||||
|
||||
struct os_mbuf *mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz,
|
||||
mem_frag_alloc_fn *alloc_cb, void *cb_arg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef __NIMBLE_PORT_H__
|
||||
#define __NIMBLE_PORT_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void nimble_init(void);
|
||||
|
||||
void nimble_run(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __NIMBLE_PORT_H__ */
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_ENDIAN_
|
||||
#define H_ENDIAN_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Internal helpers */
|
||||
#ifndef os_bswap_64
|
||||
#define os_bswap_64(x) ((uint64_t) \
|
||||
((((x) & 0xff00000000000000ull) >> 56) | \
|
||||
(((x) & 0x00ff000000000000ull) >> 40) | \
|
||||
(((x) & 0x0000ff0000000000ull) >> 24) | \
|
||||
(((x) & 0x000000ff00000000ull) >> 8) | \
|
||||
(((x) & 0x00000000ff000000ull) << 8) | \
|
||||
(((x) & 0x0000000000ff0000ull) << 24) | \
|
||||
(((x) & 0x000000000000ff00ull) << 40) | \
|
||||
(((x) & 0x00000000000000ffull) << 56)))
|
||||
#endif
|
||||
|
||||
#ifndef os_bswap_32
|
||||
#define os_bswap_32(x) ((uint32_t) \
|
||||
((((x) & 0xff000000) >> 24) | \
|
||||
(((x) & 0x00ff0000) >> 8) | \
|
||||
(((x) & 0x0000ff00) << 8) | \
|
||||
(((x) & 0x000000ff) << 24)))
|
||||
#endif
|
||||
|
||||
#ifndef os_bswap_16
|
||||
#define os_bswap_16(x) ((uint16_t) \
|
||||
((((x) & 0xff00) >> 8) | \
|
||||
(((x) & 0x00ff) << 8)))
|
||||
#endif
|
||||
|
||||
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
||||
|
||||
#ifndef ntohll
|
||||
#define ntohll(x) ((uint64_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htonll
|
||||
#define htonll(x) ((uint64_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htonl
|
||||
#define htonl(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef ntohs
|
||||
#define ntohs(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htons
|
||||
#define htons(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htobe16
|
||||
#define htobe16(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htole16
|
||||
#define htole16(x) os_bswap_16 (x)
|
||||
#endif
|
||||
|
||||
#ifndef be16toh
|
||||
#define be16toh(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef le16toh
|
||||
#define le16toh(x) os_bswap_16 (x)
|
||||
#endif
|
||||
|
||||
#ifndef htobe32
|
||||
#define htobe32(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htole32
|
||||
#define htole32(x) os_bswap_32 (x)
|
||||
#endif
|
||||
|
||||
#ifndef be32toh
|
||||
#define be32toh(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef le32toh
|
||||
#define le32toh(x) os_bswap_32 (x)
|
||||
#endif
|
||||
|
||||
#ifndef htobe64
|
||||
#define htobe64(x) ((uint64_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htole64
|
||||
#define htole64(x) os_bswap_64 (x)
|
||||
#endif
|
||||
|
||||
#ifndef be64toh
|
||||
#define be64toh(x) ((uint64_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef le64toh
|
||||
#define le64toh(x) os_bswap_64 (x)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifndef ntohll
|
||||
#define ntohll(x) os_bswap_64(x)
|
||||
#endif
|
||||
|
||||
#ifndef htonll
|
||||
#define htonll ntohll
|
||||
#endif
|
||||
|
||||
#ifndef ntohl
|
||||
#define ntohl(x) os_bswap_32(x)
|
||||
#endif
|
||||
|
||||
#ifndef htonl
|
||||
#define htonl ntohl
|
||||
#endif
|
||||
|
||||
#ifndef htons
|
||||
#define htons(x) os_bswap_16(x)
|
||||
#endif
|
||||
|
||||
#ifndef ntohs
|
||||
#define ntohs htons
|
||||
#endif
|
||||
|
||||
#ifndef htobe16
|
||||
#define htobe16(x) os_bswap_16(x)
|
||||
#endif
|
||||
|
||||
#ifndef htole16
|
||||
#define htole16(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef be16toh
|
||||
#define be16toh(x) os_bswap_16(x)
|
||||
#endif
|
||||
|
||||
#ifndef le16toh
|
||||
#define le16toh(x) ((uint16_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htobe32
|
||||
#define htobe32(x) os_bswap_32(x)
|
||||
#endif
|
||||
|
||||
#ifndef htole32
|
||||
#define htole32(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef be32toh
|
||||
#define be32toh(x) os_bswap_32(x)
|
||||
#endif
|
||||
|
||||
#ifndef le32toh
|
||||
#define le32toh(x) ((uint32_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef htobe64
|
||||
#define htobe64(x) os_bswap64(x)
|
||||
#endif
|
||||
|
||||
#ifndef htole64
|
||||
#define htole64(x) ((uint64_t)(x))
|
||||
#endif
|
||||
|
||||
#ifndef be64toh
|
||||
#define be64toh(x) os_bswap64(x)
|
||||
#endif
|
||||
|
||||
#ifndef le64toh
|
||||
#define le64toh(x) ((uint64_t)(x))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
void put_le16(void *buf, uint16_t x);
|
||||
void put_le32(void *buf, uint32_t x);
|
||||
void put_le64(void *buf, uint64_t x);
|
||||
uint16_t get_le16(const void *buf);
|
||||
uint32_t get_le32(const void *buf);
|
||||
uint64_t get_le64(const void *buf);
|
||||
void put_be16(void *buf, uint16_t x);
|
||||
void put_be32(void *buf, uint32_t x);
|
||||
void put_be64(void *buf, uint64_t x);
|
||||
uint16_t get_be16(const void *buf);
|
||||
uint32_t get_be32(const void *buf);
|
||||
uint64_t get_be64(const void *buf);
|
||||
void swap_in_place(void *buf, int len);
|
||||
void swap_buf(uint8_t *dst, const uint8_t *src, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_H
|
||||
#define _OS_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
#define min(a, b) ((a)<(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a, b) ((a)>(b)?(a):(b))
|
||||
#endif
|
||||
|
||||
#define os_get_return_addr() (__builtin_return_address(0))
|
||||
|
||||
#define OS_ALIGN(__n, __a) ( \
|
||||
(((__n) & ((__a) - 1)) == 0) ? \
|
||||
(__n) : \
|
||||
((__n) + ((__a) - ((__n) & ((__a) - 1)))) \
|
||||
)
|
||||
|
||||
|
||||
#define CTASSERT(x) typedef int __ctasssert ## __LINE__[(x) ? 1 : -1]
|
||||
|
||||
|
||||
/**
|
||||
* Whether or not the operating system has been started. Set to
|
||||
* 1 right before first task is run.
|
||||
*/
|
||||
extern int g_os_started;
|
||||
|
||||
int os_info_init(void);
|
||||
|
||||
/**
|
||||
* Returns 1 if the OS has been started, 0 if it has not yet been
|
||||
* been started.
|
||||
*/
|
||||
int os_started(void);
|
||||
|
||||
#define OS_WAIT_FOREVER (-1)
|
||||
|
||||
#define OS_IDLE_PRIO (0xff)
|
||||
#define OS_MAIN_TASK_PRIO MYNEWT_VAL(OS_MAIN_TASK_PRIO)
|
||||
#define OS_MAIN_STACK_SIZE MYNEWT_VAL(OS_MAIN_STACK_SIZE)
|
||||
|
||||
void os_init(int (*fn)(int argc, char **argv));
|
||||
void os_start(void);
|
||||
|
||||
/* XXX: Not sure if this should go here; I want to differentiate API that
|
||||
* should be called by application developers as those that should not. */
|
||||
void os_init_idle_task(void);
|
||||
|
||||
#include "os/endian.h"
|
||||
#include "os/os_arch.h"
|
||||
#include "os/os_callout.h"
|
||||
#include "os/os_cputime.h"
|
||||
#include "os/os_dev.h"
|
||||
#include "os/os_error.h"
|
||||
#include "os/os_eventq.h"
|
||||
#include "os/os_heap.h"
|
||||
#include "os/os_fault.h"
|
||||
#include "os/os_mbuf.h"
|
||||
#include "os/os_mempool.h"
|
||||
#include "os/os_mutex.h"
|
||||
#include "os/os_sanity.h"
|
||||
#include "os/os_sched.h"
|
||||
#include "os/os_sem.h"
|
||||
#include "os/os_task.h"
|
||||
#include "os/os_time.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_H */
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
#ifndef _OS_ARCH_H
|
||||
#define _OS_ARCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int os_sr_t;
|
||||
typedef int os_stack_t;
|
||||
|
||||
#define OS_ALIGNMENT (4)
|
||||
#define OS_TICKS_PER_SEC (1000)
|
||||
|
||||
extern void vPortEnterCritical(void);
|
||||
extern void vPortExitCritical(void);
|
||||
|
||||
#define OS_ENTER_CRITICAL(unused) do { (void)unused; vPortEnterCritical(); } while (0)
|
||||
#define OS_EXIT_CRITICAL(unused) do { (void)unused; vPortExitCritical(); } while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_ARCH_H */
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _OS_CALLOUT_H
|
||||
#define _OS_CALLOUT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define OS_CALLOUT_F_QUEUED (0x01)
|
||||
|
||||
#include "os/os_eventq.h"
|
||||
|
||||
struct os_callout {
|
||||
struct os_event c_ev;
|
||||
struct os_eventq *c_evq;
|
||||
uint32_t c_ticks;
|
||||
TAILQ_ENTRY(os_callout) c_next;
|
||||
};
|
||||
|
||||
TAILQ_HEAD(os_callout_list, os_callout);
|
||||
|
||||
void os_callout_init(struct os_callout *cf, struct os_eventq *evq,
|
||||
os_event_fn *ev_cb, void *ev_arg);
|
||||
void os_callout_stop(struct os_callout *);
|
||||
int os_callout_reset(struct os_callout *, int32_t);
|
||||
void os_callout_tick(void);
|
||||
os_time_t os_callout_wakeup_ticks(os_time_t now);
|
||||
os_time_t os_callout_remaining_ticks(struct os_callout *c, os_time_t now);
|
||||
|
||||
static inline int
|
||||
os_callout_queued(struct os_callout *c)
|
||||
{
|
||||
return c->c_next.tqe_prev != NULL;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_CALLOUT_H */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _OS_CFG_H_
|
||||
#define _OS_CFG_H_
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_CFG_H_ */
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_OS_CPUTIME_
|
||||
#define H_OS_CPUTIME_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/queue.h"
|
||||
#include "hal/hal_timer.h"
|
||||
|
||||
/*
|
||||
* NOTE: these definitions allow one to override the cputime frequency used.
|
||||
* The reason these definitions exist is to make the code more
|
||||
* efficient/smaller when CPUTIME counts at 1 MHz.
|
||||
*
|
||||
* For those who want a different cputime frequency, you can set the config
|
||||
* definition for OS_CPUTIME_FREQ to the desired frequency in your project,
|
||||
* target or bsp.
|
||||
*/
|
||||
#if (MYNEWT_VAL(OS_CPUTIME_FREQ) == 1000000)
|
||||
|
||||
#define OS_CPUTIME_FREQ_1MHZ
|
||||
|
||||
#elif MYNEWT_VAL(OS_CPUTIME_FREQ) == 256 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 512 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 1024 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 2048 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 4096 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 8192 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 16384 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 32768 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 65536 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 131072 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 262144 || \
|
||||
MYNEWT_VAL(OS_CPUTIME_FREQ) == 524288
|
||||
|
||||
#define OS_CPUTIME_FREQ_PWR2
|
||||
|
||||
#elif MYNEWT_VAL(OS_CPUTIME_FREQ) > 1000000
|
||||
|
||||
#define OS_CPUTIME_FREQ_HIGH
|
||||
|
||||
#else
|
||||
|
||||
#error "Invalid OS_CPUTIME_FREQ value. Value must be one of a) a power of 2" \
|
||||
">= 256Hz, or b) any value >= 1MHz"
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(OS_CPUTIME_FREQ_HIGH)
|
||||
/* CPUTIME data. */
|
||||
struct os_cputime_data
|
||||
{
|
||||
uint32_t ticks_per_usec; /* number of ticks per usec */
|
||||
};
|
||||
extern struct os_cputime_data g_os_cputime;
|
||||
#endif
|
||||
|
||||
/* Helpful macros to compare cputimes */
|
||||
#define CPUTIME_LT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) < 0)
|
||||
#define CPUTIME_GT(__t1, __t2) ((int32_t) ((__t1) - (__t2)) > 0)
|
||||
#define CPUTIME_GEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) >= 0)
|
||||
#define CPUTIME_LEQ(__t1, __t2) ((int32_t) ((__t1) - (__t2)) <= 0)
|
||||
|
||||
/**
|
||||
* os cputime init
|
||||
*
|
||||
* Initialize the cputime module. This must be called after os_init is called
|
||||
* and before any other timer API are used. This should be called only once
|
||||
* and should be called before the hardware timer is used.
|
||||
*
|
||||
* @param clock_freq The desired cputime frequency, in hertz (Hz).
|
||||
*
|
||||
* @return int 0 on success; -1 on error.
|
||||
*/
|
||||
int os_cputime_init(uint32_t clock_freq);
|
||||
|
||||
/**
|
||||
* os cputime get32
|
||||
*
|
||||
* Returns the low 32 bits of cputime.
|
||||
*
|
||||
* @return uint32_t The lower 32 bits of cputime
|
||||
*/
|
||||
uint32_t os_cputime_get32(void);
|
||||
|
||||
#if !defined(OS_CPUTIME_FREQ_PWR2)
|
||||
/**
|
||||
* os cputime nsecs to ticks
|
||||
*
|
||||
* Converts the given number of nanoseconds into cputime ticks.
|
||||
*
|
||||
* @param usecs The number of nanoseconds to convert to ticks
|
||||
*
|
||||
* @return uint32_t The number of ticks corresponding to 'nsecs'
|
||||
*/
|
||||
uint32_t os_cputime_nsecs_to_ticks(uint32_t nsecs);
|
||||
|
||||
/**
|
||||
* os cputime ticks to nsecs
|
||||
*
|
||||
* Convert the given number of ticks into nanoseconds.
|
||||
*
|
||||
* @param ticks The number of ticks to convert to nanoseconds.
|
||||
*
|
||||
* @return uint32_t The number of nanoseconds corresponding to 'ticks'
|
||||
*/
|
||||
uint32_t os_cputime_ticks_to_nsecs(uint32_t ticks);
|
||||
|
||||
/**
|
||||
* os cputime delay nsecs
|
||||
*
|
||||
* Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay.
|
||||
*
|
||||
* @param nsecs The number of nanoseconds to wait.
|
||||
*/
|
||||
void os_cputime_delay_nsecs(uint32_t nsecs);
|
||||
#endif
|
||||
|
||||
#if defined(OS_CPUTIME_FREQ_1MHZ)
|
||||
#define os_cputime_usecs_to_ticks(x) (x)
|
||||
#define os_cputime_ticks_to_usecs(x) (x)
|
||||
#else
|
||||
/**
|
||||
* os cputime usecs to ticks
|
||||
*
|
||||
* Converts the given number of microseconds into cputime ticks.
|
||||
*
|
||||
* @param usecs The number of microseconds to convert to ticks
|
||||
*
|
||||
* @return uint32_t The number of ticks corresponding to 'usecs'
|
||||
*/
|
||||
uint32_t os_cputime_usecs_to_ticks(uint32_t usecs);
|
||||
|
||||
/**
|
||||
* os cputime ticks to usecs
|
||||
*
|
||||
* Convert the given number of ticks into microseconds.
|
||||
*
|
||||
* @param ticks The number of ticks to convert to microseconds.
|
||||
*
|
||||
* @return uint32_t The number of microseconds corresponding to 'ticks'
|
||||
*/
|
||||
uint32_t os_cputime_ticks_to_usecs(uint32_t ticks);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* os cputime delay ticks
|
||||
*
|
||||
* Wait until the number of ticks has elapsed. This is a blocking delay.
|
||||
*
|
||||
* @param ticks The number of ticks to wait.
|
||||
*/
|
||||
void os_cputime_delay_ticks(uint32_t ticks);
|
||||
|
||||
/**
|
||||
* os cputime delay usecs
|
||||
*
|
||||
* Wait until 'usecs' microseconds has elapsed. This is a blocking delay.
|
||||
*
|
||||
* @param usecs The number of usecs to wait.
|
||||
*/
|
||||
void os_cputime_delay_usecs(uint32_t usecs);
|
||||
|
||||
/**
|
||||
* os cputime timer init
|
||||
*
|
||||
* @param timer The timer to initialize. Cannot be NULL.
|
||||
* @param fp The timer callback function. Cannot be NULL.
|
||||
* @param arg Pointer to data object to pass to timer.
|
||||
*/
|
||||
void os_cputime_timer_init(struct hal_timer *timer, hal_timer_cb fp, void *arg);
|
||||
|
||||
/**
|
||||
* os cputime timer start
|
||||
*
|
||||
* Start a cputimer that will expire at 'cputime'. If cputime has already
|
||||
* passed, the timer callback will still be called (at interrupt context).
|
||||
*
|
||||
* NOTE: This must be called when the timer is stopped.
|
||||
*
|
||||
* @param timer Pointer to timer to start. Cannot be NULL.
|
||||
* @param cputime The cputime at which the timer should expire.
|
||||
*
|
||||
* @return int 0 on success; EINVAL if timer already started or timer struct
|
||||
* invalid
|
||||
*
|
||||
*/
|
||||
int os_cputime_timer_start(struct hal_timer *timer, uint32_t cputime);
|
||||
|
||||
/**
|
||||
* os cputimer timer relative
|
||||
*
|
||||
* Sets a cpu timer that will expire 'usecs' microseconds from the current
|
||||
* cputime.
|
||||
*
|
||||
* NOTE: This must be called when the timer is stopped.
|
||||
*
|
||||
* @param timer Pointer to timer. Cannot be NULL.
|
||||
* @param usecs The number of usecs from now at which the timer will expire.
|
||||
*
|
||||
* @return int 0 on success; EINVAL if timer already started or timer struct
|
||||
* invalid
|
||||
*/
|
||||
int os_cputime_timer_relative(struct hal_timer *timer, uint32_t usecs);
|
||||
|
||||
/**
|
||||
* os cputime timer stop
|
||||
*
|
||||
* Stops a cputimer from running. The timer is removed from the timer queue
|
||||
* and interrupts are disabled if no timers are left on the queue. Can be
|
||||
* called even if timer is not running.
|
||||
*
|
||||
* @param timer Pointer to cputimer to stop. Cannot be NULL.
|
||||
*/
|
||||
void os_cputime_timer_stop(struct hal_timer *timer);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_OS_CPUTIME_ */
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_DEV_H
|
||||
#define _OS_DEV_H
|
||||
|
||||
#include <os/os.h>
|
||||
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_dev;
|
||||
|
||||
/*
|
||||
* Initialization order, defines when a device should be initialized
|
||||
* by the Mynewt kernel.
|
||||
*
|
||||
*/
|
||||
#define OS_DEV_INIT_PRIMARY (1)
|
||||
#define OS_DEV_INIT_SECONDARY (2)
|
||||
#define OS_DEV_INIT_KERNEL (3)
|
||||
|
||||
#define OS_DEV_INIT_F_CRITICAL (1 << 0)
|
||||
|
||||
|
||||
#define OS_DEV_INIT_PRIO_DEFAULT (0xff)
|
||||
|
||||
/**
|
||||
* Device status, so functions can ensure device is called in a
|
||||
* consistent state.
|
||||
*/
|
||||
#define OS_DEV_F_STATUS_READY (1 << 0)
|
||||
#define OS_DEV_F_STATUS_OPEN (1 << 1)
|
||||
#define OS_DEV_F_STATUS_SUSPENDED (1 << 2)
|
||||
#define OS_DEV_F_INIT_CRITICAL (1 << 3)
|
||||
|
||||
typedef int (*os_dev_init_func_t)(struct os_dev *, void *);
|
||||
typedef int (*os_dev_open_func_t)(struct os_dev *, uint32_t,
|
||||
void *);
|
||||
typedef int (*os_dev_suspend_func_t)(struct os_dev *, os_time_t, int);
|
||||
typedef int (*os_dev_resume_func_t)(struct os_dev *);
|
||||
typedef int (*os_dev_close_func_t)(struct os_dev *);
|
||||
|
||||
struct os_dev_handlers {
|
||||
os_dev_open_func_t od_open;
|
||||
os_dev_suspend_func_t od_suspend;
|
||||
os_dev_resume_func_t od_resume;
|
||||
os_dev_close_func_t od_close;
|
||||
};
|
||||
|
||||
/*
|
||||
* Device structure.
|
||||
*/
|
||||
struct os_dev {
|
||||
struct os_dev_handlers od_handlers;
|
||||
os_dev_init_func_t od_init;
|
||||
void *od_init_arg;
|
||||
uint8_t od_stage;
|
||||
uint8_t od_priority;
|
||||
uint8_t od_open_ref;
|
||||
uint8_t od_flags;
|
||||
char *od_name;
|
||||
STAILQ_ENTRY(os_dev) od_next;
|
||||
};
|
||||
|
||||
#define OS_DEV_SETHANDLERS(__dev, __open, __close) \
|
||||
(__dev)->od_handlers.od_open = (__open); \
|
||||
(__dev)->od_handlers.od_close = (__close);
|
||||
|
||||
static inline int
|
||||
os_dev_suspend(struct os_dev *dev, os_time_t suspend_t, uint8_t force)
|
||||
{
|
||||
if (dev->od_handlers.od_suspend == NULL) {
|
||||
return (0);
|
||||
} else {
|
||||
return (dev->od_handlers.od_suspend(dev, suspend_t, force));
|
||||
}
|
||||
}
|
||||
|
||||
static inline int
|
||||
os_dev_resume(struct os_dev *dev)
|
||||
{
|
||||
if (dev->od_handlers.od_resume == NULL) {
|
||||
return (0);
|
||||
} else {
|
||||
return (dev->od_handlers.od_resume(dev));
|
||||
}
|
||||
}
|
||||
|
||||
int os_dev_create(struct os_dev *dev, char *name, uint8_t stage,
|
||||
uint8_t priority, os_dev_init_func_t od_init, void *arg);
|
||||
struct os_dev *os_dev_lookup(char *name);
|
||||
int os_dev_initialize_all(uint8_t stage);
|
||||
int os_dev_suspend_all(os_time_t, uint8_t);
|
||||
int os_dev_resume_all(void);
|
||||
struct os_dev *os_dev_open(char *devname, uint32_t timo, void *arg);
|
||||
int os_dev_close(struct os_dev *dev);
|
||||
void os_dev_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_DEV_H */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_OS_ERROR_
|
||||
#define H_OS_ERROR_
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* OS error enumerations */
|
||||
enum os_error {
|
||||
OS_OK = 0,
|
||||
OS_ENOMEM = 1,
|
||||
OS_EINVAL = 2,
|
||||
OS_INVALID_PARM = 3,
|
||||
OS_MEM_NOT_ALIGNED = 4,
|
||||
OS_BAD_MUTEX = 5,
|
||||
OS_TIMEOUT = 6,
|
||||
OS_ERR_IN_ISR = 7, /* Function cannot be called from ISR */
|
||||
OS_ERR_PRIV = 8, /* Privileged access error */
|
||||
OS_NOT_STARTED = 9, /* OS must be started to call this function, but isn't */
|
||||
OS_ENOENT = 10, /* No such thing */
|
||||
OS_EBUSY = 11, /* Resource busy */
|
||||
OS_ERROR = 12, /* Generic Error */
|
||||
};
|
||||
|
||||
typedef enum os_error os_error_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_EVENTQ_H
|
||||
#define _OS_EVENTQ_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "os/os_time.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_event;
|
||||
typedef void os_event_fn(struct os_event *ev);
|
||||
|
||||
struct os_event {
|
||||
uint8_t ev_queued;
|
||||
os_event_fn *ev_cb;
|
||||
void *ev_arg;
|
||||
STAILQ_ENTRY(os_event) ev_next;
|
||||
};
|
||||
|
||||
#define OS_EVENT_QUEUED(__ev) ((__ev)->ev_queued)
|
||||
|
||||
struct os_eventq {
|
||||
struct os_task *evq_owner; /* owner task */
|
||||
struct os_task *evq_task; /* sleeper; must be either NULL, or the owner */
|
||||
STAILQ_HEAD(, os_event) evq_list;
|
||||
};
|
||||
|
||||
void os_eventq_init(struct os_eventq *);
|
||||
int os_eventq_inited(const struct os_eventq *evq);
|
||||
void os_eventq_put(struct os_eventq *, struct os_event *);
|
||||
struct os_event *os_eventq_get_no_wait(struct os_eventq *evq);
|
||||
struct os_event *os_eventq_get(struct os_eventq *);
|
||||
void os_eventq_run(struct os_eventq *evq);
|
||||
struct os_event *os_eventq_poll(struct os_eventq **, int, os_time_t);
|
||||
void os_eventq_remove(struct os_eventq *, struct os_event *);
|
||||
struct os_eventq *os_eventq_dflt_get(void);
|
||||
|
||||
/* [DEPRECATED] */
|
||||
void os_eventq_designate(struct os_eventq **dst, struct os_eventq *val,
|
||||
struct os_event *start_ev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_EVENTQ_H */
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_FAULT_H
|
||||
#define _OS_FAULT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "c" {
|
||||
#endif
|
||||
|
||||
void __assert_func(const char *, int, const char *, const char *)
|
||||
__attribute((noreturn));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_FAULT_H */
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_OS_HEAP_
|
||||
#define H_OS_HEAP_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void *os_malloc(size_t size);
|
||||
void os_free(void *mem);
|
||||
void *os_realloc(void *ptr, size_t size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_OS_MALLOC_
|
||||
#define H_OS_MALLOC_
|
||||
|
||||
#include "os/os_heap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#undef malloc
|
||||
#define malloc os_malloc
|
||||
|
||||
#undef free
|
||||
#define free os_free
|
||||
|
||||
#undef realloc
|
||||
#define realloc os_realloc
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,305 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_MBUF_H
|
||||
#define _OS_MBUF_H
|
||||
|
||||
#include "os/queue.h"
|
||||
#include "os/os_eventq.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A mbuf pool from which to allocate mbufs. This contains a pointer to the os
|
||||
* mempool to allocate mbufs out of, the total number of elements in the pool,
|
||||
* and the amount of "user" data in a non-packet header mbuf. The total pool
|
||||
* size, in bytes, should be:
|
||||
* os_mbuf_count * (omp_databuf_len + sizeof(struct os_mbuf))
|
||||
*/
|
||||
struct os_mbuf_pool {
|
||||
/**
|
||||
* Total length of the databuf in each mbuf. This is the size of the
|
||||
* mempool block, minus the mbuf header
|
||||
*/
|
||||
uint16_t omp_databuf_len;
|
||||
/**
|
||||
* Total number of memblock's allocated in this mempool.
|
||||
*/
|
||||
uint16_t omp_mbuf_count;
|
||||
/**
|
||||
* The memory pool which to allocate mbufs out of
|
||||
*/
|
||||
struct os_mempool *omp_pool;
|
||||
|
||||
/**
|
||||
* Link to the next mbuf pool for system memory pools.
|
||||
*/
|
||||
STAILQ_ENTRY(os_mbuf_pool) omp_next;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A packet header structure that preceeds the mbuf packet headers.
|
||||
*/
|
||||
struct os_mbuf_pkthdr {
|
||||
/**
|
||||
* Overall length of the packet.
|
||||
*/
|
||||
uint16_t omp_len;
|
||||
/**
|
||||
* Flags
|
||||
*/
|
||||
uint16_t omp_flags;
|
||||
/**
|
||||
* Next packet in the mbuf chain.
|
||||
*/
|
||||
STAILQ_ENTRY(os_mbuf_pkthdr) omp_next;
|
||||
};
|
||||
|
||||
/**
|
||||
* Chained memory buffer.
|
||||
*/
|
||||
struct os_mbuf {
|
||||
/**
|
||||
* Current pointer to data in the structure
|
||||
*/
|
||||
uint8_t *om_data;
|
||||
/**
|
||||
* Flags associated with this buffer, see OS_MBUF_F_* defintions
|
||||
*/
|
||||
uint8_t om_flags;
|
||||
/**
|
||||
* Length of packet header
|
||||
*/
|
||||
uint8_t om_pkthdr_len;
|
||||
/**
|
||||
* Length of data in this buffer
|
||||
*/
|
||||
uint16_t om_len;
|
||||
|
||||
/**
|
||||
* The mbuf pool this mbuf was allocated out of
|
||||
*/
|
||||
struct os_mbuf_pool *om_omp;
|
||||
|
||||
/**
|
||||
* Pointer to next entry in the chained memory buffer
|
||||
*/
|
||||
SLIST_ENTRY(os_mbuf) om_next;
|
||||
|
||||
/**
|
||||
* Pointer to the beginning of the data, after this buffer
|
||||
*/
|
||||
uint8_t om_databuf[0];
|
||||
};
|
||||
|
||||
struct os_mqueue {
|
||||
STAILQ_HEAD(, os_mbuf_pkthdr) mq_head;
|
||||
struct os_event mq_ev;
|
||||
};
|
||||
|
||||
/*
|
||||
* Given a flag number, provide the mask for it
|
||||
*
|
||||
* @param __n The number of the flag in the mask
|
||||
*/
|
||||
#define OS_MBUF_F_MASK(__n) (1 << (__n))
|
||||
|
||||
/*
|
||||
* Checks whether a given mbuf is a packet header mbuf
|
||||
*
|
||||
* @param __om The mbuf to check
|
||||
*/
|
||||
#define OS_MBUF_IS_PKTHDR(__om) \
|
||||
((__om)->om_pkthdr_len >= sizeof (struct os_mbuf_pkthdr))
|
||||
|
||||
/* Get a packet header pointer given an mbuf pointer */
|
||||
#define OS_MBUF_PKTHDR(__om) ((struct os_mbuf_pkthdr *) \
|
||||
((uint8_t *)&(__om)->om_data + sizeof(struct os_mbuf)))
|
||||
|
||||
/* Given a mbuf packet header pointer, return a pointer to the mbuf */
|
||||
#define OS_MBUF_PKTHDR_TO_MBUF(__hdr) \
|
||||
(struct os_mbuf *)((uint8_t *)(__hdr) - sizeof(struct os_mbuf))
|
||||
|
||||
/**
|
||||
* Gets the length of an entire mbuf chain. The specified mbuf must have a
|
||||
* packet header.
|
||||
*/
|
||||
#define OS_MBUF_PKTLEN(__om) (OS_MBUF_PKTHDR(__om)->omp_len)
|
||||
|
||||
/*
|
||||
* Access the data of a mbuf, and cast it to type
|
||||
*
|
||||
* @param __om The mbuf to access, and cast
|
||||
* @param __type The type to cast it to
|
||||
*/
|
||||
#define OS_MBUF_DATA(__om, __type) \
|
||||
(__type) ((__om)->om_data)
|
||||
|
||||
/**
|
||||
* Access the "user header" in the head of an mbuf chain.
|
||||
*
|
||||
* @param om Pointer to the head of an mbuf chain.
|
||||
*/
|
||||
#define OS_MBUF_USRHDR(om) \
|
||||
(void *)((uint8_t *)om + sizeof (struct os_mbuf) + \
|
||||
sizeof (struct os_mbuf_pkthdr))
|
||||
|
||||
/**
|
||||
* Retrieves the length of the user header in an mbuf.
|
||||
*
|
||||
* @param om Pointer to the mbuf to query.
|
||||
*/
|
||||
#define OS_MBUF_USRHDR_LEN(om) \
|
||||
((om)->om_pkthdr_len - sizeof (struct os_mbuf_pkthdr))
|
||||
|
||||
/*
|
||||
* Called by OS_MBUF_LEADINGSPACE() macro
|
||||
*/
|
||||
static inline uint16_t
|
||||
_os_mbuf_leadingspace(struct os_mbuf *om)
|
||||
{
|
||||
uint16_t startoff;
|
||||
uint16_t leadingspace;
|
||||
|
||||
startoff = 0;
|
||||
if (OS_MBUF_IS_PKTHDR(om)) {
|
||||
startoff = om->om_pkthdr_len;
|
||||
}
|
||||
|
||||
leadingspace = (uint16_t) (OS_MBUF_DATA(om, uint8_t *) -
|
||||
((uint8_t *) &om->om_databuf[0] + startoff));
|
||||
|
||||
return (leadingspace);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the leading space (space at the beginning) of the mbuf.
|
||||
* Works on both packet header, and regular mbufs, as it accounts
|
||||
* for the additional space allocated to the packet header.
|
||||
*
|
||||
* @param __omp Is the mbuf pool (which contains packet header length.)
|
||||
* @param __om Is the mbuf in that pool to get the leadingspace for
|
||||
*
|
||||
* @return Amount of leading space available in the mbuf
|
||||
*/
|
||||
#define OS_MBUF_LEADINGSPACE(__om) _os_mbuf_leadingspace(__om)
|
||||
|
||||
/* Called by OS_MBUF_TRAILINGSPACE() macro. */
|
||||
static inline uint16_t
|
||||
_os_mbuf_trailingspace(struct os_mbuf *om)
|
||||
{
|
||||
struct os_mbuf_pool *omp;
|
||||
|
||||
omp = om->om_omp;
|
||||
|
||||
return (&om->om_databuf[0] + omp->omp_databuf_len) -
|
||||
(om->om_data + om->om_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the trailing space (space at the end) of the mbuf.
|
||||
* Works on both packet header and regular mbufs.
|
||||
*
|
||||
* @param __omp The mbuf pool for this mbuf
|
||||
* @param __om Is the mbuf in that pool to get trailing space for
|
||||
*
|
||||
* @return The amount of trailing space available in the mbuf
|
||||
*/
|
||||
#define OS_MBUF_TRAILINGSPACE(__om) _os_mbuf_trailingspace(__om)
|
||||
|
||||
/* Mbuf queue functions */
|
||||
|
||||
/* Initialize a mbuf queue */
|
||||
int os_mqueue_init(struct os_mqueue *mq, os_event_fn *ev_cb, void *arg);
|
||||
|
||||
/* Get an element from a mbuf queue */
|
||||
struct os_mbuf *os_mqueue_get(struct os_mqueue *);
|
||||
|
||||
/* Put an element in a mbuf queue */
|
||||
int os_mqueue_put(struct os_mqueue *, struct os_eventq *, struct os_mbuf *);
|
||||
|
||||
/* Register an mbuf pool with the system pool registry */
|
||||
int os_msys_register(struct os_mbuf_pool *);
|
||||
|
||||
/* Return a mbuf from the system pool, given an indicative mbuf size */
|
||||
struct os_mbuf *os_msys_get(uint16_t dsize, uint16_t leadingspace);
|
||||
|
||||
/* De-registers all mbuf pools from msys. */
|
||||
void os_msys_reset(void);
|
||||
|
||||
/* Return a packet header mbuf from the system pool */
|
||||
struct os_mbuf *os_msys_get_pkthdr(uint16_t dsize, uint16_t user_hdr_len);
|
||||
|
||||
int os_msys_count(void);
|
||||
int os_msys_num_free(void);
|
||||
|
||||
/* Initialize a mbuf pool */
|
||||
int os_mbuf_pool_init(struct os_mbuf_pool *, struct os_mempool *mp,
|
||||
uint16_t, uint16_t);
|
||||
|
||||
/* Allocate a new mbuf out of the os_mbuf_pool */
|
||||
struct os_mbuf *os_mbuf_get(struct os_mbuf_pool *omp, uint16_t);
|
||||
|
||||
/* Allocate a new packet header mbuf out of the os_mbuf_pool */
|
||||
struct os_mbuf *os_mbuf_get_pkthdr(struct os_mbuf_pool *omp,
|
||||
uint8_t pkthdr_len);
|
||||
|
||||
/* Duplicate a mbuf from the pool */
|
||||
struct os_mbuf *os_mbuf_dup(struct os_mbuf *m);
|
||||
|
||||
struct os_mbuf *os_mbuf_off(const struct os_mbuf *om, int off,
|
||||
uint16_t *out_off);
|
||||
|
||||
/* Copy data from an mbuf to a flat buffer. */
|
||||
int os_mbuf_copydata(const struct os_mbuf *m, int off, int len, void *dst);
|
||||
|
||||
/* Append data onto a mbuf */
|
||||
int os_mbuf_append(struct os_mbuf *m, const void *, uint16_t);
|
||||
|
||||
int os_mbuf_appendfrom(struct os_mbuf *dst, const struct os_mbuf *src,
|
||||
uint16_t src_off, uint16_t len);
|
||||
|
||||
/* Free a mbuf */
|
||||
int os_mbuf_free(struct os_mbuf *mb);
|
||||
|
||||
/* Free a mbuf chain */
|
||||
int os_mbuf_free_chain(struct os_mbuf *om);
|
||||
|
||||
void os_mbuf_adj(struct os_mbuf *mp, int req_len);
|
||||
int os_mbuf_cmpf(const struct os_mbuf *om, int off, const void *data, int len);
|
||||
int os_mbuf_cmpm(const struct os_mbuf *om1, uint16_t offset1,
|
||||
const struct os_mbuf *om2, uint16_t offset2,
|
||||
uint16_t len);
|
||||
|
||||
struct os_mbuf *os_mbuf_prepend(struct os_mbuf *om, int len);
|
||||
struct os_mbuf *os_mbuf_prepend_pullup(struct os_mbuf *om, uint16_t len);
|
||||
int os_mbuf_copyinto(struct os_mbuf *om, int off, const void *src, int len);
|
||||
void os_mbuf_concat(struct os_mbuf *first, struct os_mbuf *second);
|
||||
void *os_mbuf_extend(struct os_mbuf *om, uint16_t len);
|
||||
struct os_mbuf *os_mbuf_pullup(struct os_mbuf *om, uint16_t len);
|
||||
struct os_mbuf *os_mbuf_trim_front(struct os_mbuf *om);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_MBUF_H */
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_MEMPOOL_H_
|
||||
#define _OS_MEMPOOL_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "os/os.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* A memory block structure. This simply contains a pointer to the free list
|
||||
* chain and is only used when the block is on the free list. When the block
|
||||
* has been removed from the free list the entire memory block is usable by the
|
||||
* caller.
|
||||
*/
|
||||
struct os_memblock {
|
||||
SLIST_ENTRY(os_memblock) mb_next;
|
||||
};
|
||||
|
||||
/* XXX: Change this structure so that we keep the first address in the pool? */
|
||||
/* XXX: add memory debug structure and associated code */
|
||||
/* XXX: Change how I coded the SLIST_HEAD here. It should be named:
|
||||
SLIST_HEAD(,os_memblock) mp_head; */
|
||||
|
||||
/* Memory pool */
|
||||
struct os_mempool {
|
||||
int mp_block_size; /* Size of the memory blocks, in bytes. */
|
||||
int mp_num_blocks; /* The number of memory blocks. */
|
||||
int mp_num_free; /* The number of free blocks left */
|
||||
int mp_min_free; /* The lowest number of free blocks seen */
|
||||
uint32_t mp_membuf_addr; /* Address of memory buffer used by pool */
|
||||
STAILQ_ENTRY(os_mempool) mp_list;
|
||||
SLIST_HEAD(,os_memblock); /* Pointer to list of free blocks */
|
||||
char *name; /* Name for memory block */
|
||||
};
|
||||
|
||||
#define OS_MEMPOOL_INFO_NAME_LEN (32)
|
||||
|
||||
struct os_mempool_info {
|
||||
int omi_block_size;
|
||||
int omi_num_blocks;
|
||||
int omi_num_free;
|
||||
int omi_min_free;
|
||||
char omi_name[OS_MEMPOOL_INFO_NAME_LEN];
|
||||
};
|
||||
|
||||
struct os_mempool *os_mempool_info_get_next(struct os_mempool *,
|
||||
struct os_mempool_info *);
|
||||
|
||||
/*
|
||||
* To calculate size of the memory buffer needed for the pool. NOTE: This size
|
||||
* is NOT in bytes! The size is the number of os_membuf_t elements required for
|
||||
* the memory pool.
|
||||
*/
|
||||
#if (OS_CFG_ALIGNMENT == OS_CFG_ALIGN_4)
|
||||
#define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + 3) / 4) * (n))
|
||||
typedef uint32_t os_membuf_t;
|
||||
#else
|
||||
#define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + 7) / 8) * (n))
|
||||
typedef uint64_t os_membuf_t;
|
||||
#endif
|
||||
|
||||
/** Calculates the number of bytes required to initialize a memory pool. */
|
||||
#define OS_MEMPOOL_BYTES(n,blksize) \
|
||||
(sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize)))
|
||||
|
||||
/* Initialize a memory pool */
|
||||
os_error_t os_mempool_init(struct os_mempool *mp, int blocks, int block_size,
|
||||
void *membuf, char *name);
|
||||
|
||||
/* Performs an integrity check of the specified mempool. */
|
||||
bool os_mempool_is_sane(const struct os_mempool *mp);
|
||||
|
||||
/* Checks if a memory block was allocated from the specified mempool. */
|
||||
int os_memblock_from(const struct os_mempool *mp, const void *block_addr);
|
||||
|
||||
/* Get a memory block from the pool */
|
||||
void *os_memblock_get(struct os_mempool *mp);
|
||||
|
||||
/* Put the memory block back into the pool */
|
||||
os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_MEMPOOL_H_ */
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_MUTEX_H_
|
||||
#define _OS_MUTEX_H_
|
||||
|
||||
#include "os/os.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_mutex
|
||||
{
|
||||
SLIST_HEAD(, os_task) mu_head; /* chain of waiting tasks */
|
||||
uint8_t _pad;
|
||||
uint8_t mu_prio; /* owner's default priority*/
|
||||
uint16_t mu_level; /* call nesting level */
|
||||
struct os_task *mu_owner; /* owners task */
|
||||
};
|
||||
|
||||
/*
|
||||
XXX: NOTES
|
||||
-> Should we add a magic number or flag to the mutex structure so
|
||||
that we know that this is a mutex? We can use it for double checking
|
||||
that a proper mutex was passed in to the API.
|
||||
-> What debug information should we add to this structure? Who last
|
||||
acquired the mutex? File/line where it was released?
|
||||
-> Should we add a name to the mutex?
|
||||
-> Should we add a "os_mutex_inspect() api?
|
||||
*/
|
||||
|
||||
/* XXX: api to create
|
||||
os_mutex_inspect();
|
||||
*/
|
||||
|
||||
/* Initialize a mutex */
|
||||
os_error_t os_mutex_init(struct os_mutex *mu);
|
||||
|
||||
/* Release a mutex */
|
||||
os_error_t os_mutex_release(struct os_mutex *mu);
|
||||
|
||||
/* Pend (wait) for a mutex */
|
||||
os_error_t os_mutex_pend(struct os_mutex *mu, uint32_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_MUTEX_H_ */
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_SANITY_H
|
||||
#define _OS_SANITY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "os/os_time.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_sanity_check;
|
||||
typedef int (*os_sanity_check_func_t)(struct os_sanity_check *, void *);
|
||||
|
||||
struct os_sanity_check {
|
||||
os_time_t sc_checkin_last;
|
||||
os_time_t sc_checkin_itvl;
|
||||
os_sanity_check_func_t sc_func;
|
||||
void *sc_arg;
|
||||
|
||||
SLIST_ENTRY(os_sanity_check) sc_next;
|
||||
|
||||
};
|
||||
|
||||
#define OS_SANITY_CHECK_SETFUNC(__sc, __f, __arg, __itvl) \
|
||||
(__sc)->sc_func = (__f); \
|
||||
(__sc)->sc_arg = (__arg); \
|
||||
(__sc)->sc_checkin_itvl = (__itvl) * OS_TICKS_PER_SEC;
|
||||
|
||||
int os_sanity_init(void);
|
||||
void os_sanity_run(void);
|
||||
|
||||
struct os_task;
|
||||
int os_sanity_task_checkin(struct os_task *);
|
||||
|
||||
int os_sanity_check_init(struct os_sanity_check *);
|
||||
int os_sanity_check_register(struct os_sanity_check *);
|
||||
int os_sanity_check_reset(struct os_sanity_check *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_SANITY_H */
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_SCHED_H
|
||||
#define _OS_SCHED_H
|
||||
|
||||
#include "os/os_task.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_task;
|
||||
|
||||
TAILQ_HEAD(os_task_list, os_task);
|
||||
|
||||
extern struct os_task *g_current_task;
|
||||
extern struct os_task_list g_os_run_list;
|
||||
extern struct os_task_list g_os_sleep_list;
|
||||
|
||||
void os_sched_ctx_sw_hook(struct os_task *);
|
||||
struct os_task *os_sched_get_current_task(void);
|
||||
void os_sched_set_current_task(struct os_task *);
|
||||
struct os_task *os_sched_next_task(void);
|
||||
void os_sched(struct os_task *);
|
||||
void os_sched_os_timer_exp(void);
|
||||
os_error_t os_sched_insert(struct os_task *);
|
||||
int os_sched_sleep(struct os_task *, os_time_t nticks);
|
||||
int os_sched_wakeup(struct os_task *);
|
||||
int os_sched_remove(struct os_task *);
|
||||
void os_sched_resort(struct os_task *);
|
||||
os_time_t os_sched_wakeup_ticks(os_time_t now);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_SCHED_H */
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_SEM_H_
|
||||
#define _OS_SEM_H_
|
||||
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_sem
|
||||
{
|
||||
SLIST_HEAD(, os_task) sem_head; /* chain of waiting tasks */
|
||||
uint16_t _pad;
|
||||
uint16_t sem_tokens; /* # of tokens */
|
||||
};
|
||||
|
||||
/*
|
||||
XXX: NOTES
|
||||
-> Should we add a magic number or flag to the semaphore structure so
|
||||
that we know that this is a semaphore? We can use it for double checking
|
||||
that a proper semaphore was passed in to the API.
|
||||
-> What debug information should we add to this structure? Who last
|
||||
acquired the semaphore? File/line where it was released?
|
||||
-> Should we add a name to the semaphore?
|
||||
-> Should we add a "os_sem_inspect() api, like ucos?
|
||||
*/
|
||||
|
||||
/* Create a semaphore */
|
||||
os_error_t os_sem_init(struct os_sem *sem, uint16_t tokens);
|
||||
|
||||
/* Release a semaphore */
|
||||
os_error_t os_sem_release(struct os_sem *sem);
|
||||
|
||||
/* Pend (wait) for a semaphore */
|
||||
os_error_t os_sem_pend(struct os_sem *sem, uint32_t timeout);
|
||||
|
||||
/* Get current semaphore's count */
|
||||
static inline uint16_t os_sem_get_count(struct os_sem *sem)
|
||||
{
|
||||
return sem->sem_tokens;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_SEM_H_ */
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_TASK_H
|
||||
#define _OS_TASK_H
|
||||
|
||||
#include "os/os.h"
|
||||
#include "os/os_sanity.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* The highest and lowest task priorities */
|
||||
#define OS_TASK_PRI_HIGHEST (0)
|
||||
#define OS_TASK_PRI_LOWEST (0xff)
|
||||
|
||||
/*
|
||||
* Generic "object" structure. All objects that a task can wait on must
|
||||
* have a SLIST_HEAD(, os_task) head_name as the first element in the object
|
||||
* structure. The element 'head_name' can be any name. See os_mutex.h or
|
||||
* os_sem.h for an example.
|
||||
*/
|
||||
struct os_task_obj {
|
||||
SLIST_HEAD(, os_task) obj_head; /* chain of waiting tasks */
|
||||
};
|
||||
|
||||
/* Task states */
|
||||
typedef enum os_task_state {
|
||||
OS_TASK_READY = 1,
|
||||
OS_TASK_SLEEP = 2,
|
||||
} os_task_state_t;
|
||||
|
||||
/* Task flags */
|
||||
#define OS_TASK_FLAG_NO_TIMEOUT (0x01U)
|
||||
#define OS_TASK_FLAG_SEM_WAIT (0x02U)
|
||||
#define OS_TASK_FLAG_MUTEX_WAIT (0x04U)
|
||||
#define OS_TASK_FLAG_EVQ_WAIT (0x08U)
|
||||
|
||||
typedef void (*os_task_func_t)(void *);
|
||||
|
||||
#define OS_TASK_MAX_NAME_LEN (32)
|
||||
|
||||
struct os_task {
|
||||
os_stack_t *t_stackptr;
|
||||
os_stack_t *t_stacktop;
|
||||
|
||||
uint16_t t_stacksize;
|
||||
uint8_t t_taskid;
|
||||
uint8_t t_prio;
|
||||
|
||||
uint8_t t_state;
|
||||
uint8_t t_flags;
|
||||
uint8_t t_lockcnt;
|
||||
uint8_t t_pad;
|
||||
|
||||
const char *t_name;
|
||||
os_task_func_t t_func;
|
||||
void *t_arg;
|
||||
|
||||
void *t_obj;
|
||||
|
||||
struct os_sanity_check t_sanity_check;
|
||||
|
||||
os_time_t t_next_wakeup;
|
||||
os_time_t t_run_time;
|
||||
uint32_t t_ctx_sw_cnt;
|
||||
|
||||
/* Global list of all tasks, irrespective of run or sleep lists */
|
||||
STAILQ_ENTRY(os_task) t_os_task_list;
|
||||
|
||||
/* Used to chain task to either the run or sleep list */
|
||||
TAILQ_ENTRY(os_task) t_os_list;
|
||||
|
||||
/* Used to chain task to an object such as a semaphore or mutex */
|
||||
SLIST_ENTRY(os_task) t_obj_list;
|
||||
};
|
||||
|
||||
STAILQ_HEAD(os_task_stailq, os_task);
|
||||
|
||||
extern struct os_task_stailq g_os_task_list;
|
||||
|
||||
int os_task_init(struct os_task *, const char *, os_task_func_t, void *,
|
||||
uint8_t, os_time_t, os_stack_t *, uint16_t);
|
||||
|
||||
int os_task_remove(struct os_task *t);
|
||||
|
||||
uint8_t os_task_count(void);
|
||||
|
||||
struct os_task_info {
|
||||
uint8_t oti_prio;
|
||||
uint8_t oti_taskid;
|
||||
uint8_t oti_state;
|
||||
uint16_t oti_stkusage;
|
||||
uint16_t oti_stksize;
|
||||
uint32_t oti_cswcnt;
|
||||
uint32_t oti_runtime;
|
||||
os_time_t oti_last_checkin;
|
||||
os_time_t oti_next_checkin;
|
||||
|
||||
char oti_name[OS_TASK_MAX_NAME_LEN];
|
||||
};
|
||||
|
||||
struct os_task *os_task_info_get_next(const struct os_task *,
|
||||
struct os_task_info *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_TASK_H */
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_OS_TEST_
|
||||
#define H_OS_TEST_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int os_test_all(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)time.h 8.5 (Berkeley) 5/4/95
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _OS_TIME_H
|
||||
#define _OS_TIME_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef UINT32_MAX
|
||||
#define UINT32_MAX 0xFFFFFFFFU
|
||||
#endif
|
||||
|
||||
typedef uint32_t os_time_t;
|
||||
typedef int32_t os_stime_t;
|
||||
#define OS_TIME_MAX UINT32_MAX
|
||||
|
||||
/* Used to wait forever for events and mutexs */
|
||||
#define OS_TIMEOUT_NEVER (UINT32_MAX)
|
||||
|
||||
os_time_t os_time_get(void);
|
||||
void os_time_advance(int ticks);
|
||||
void os_time_delay(int32_t osticks);
|
||||
|
||||
#define OS_TIME_TICK_LT(__t1, __t2) ((os_stime_t) ((__t1) - (__t2)) < 0)
|
||||
#define OS_TIME_TICK_GT(__t1, __t2) ((os_stime_t) ((__t1) - (__t2)) > 0)
|
||||
#define OS_TIME_TICK_GEQ(__t1, __t2) ((os_stime_t) ((__t1) - (__t2)) >= 0)
|
||||
|
||||
struct os_timeval {
|
||||
int64_t tv_sec; /* seconds since Jan 1 1970 */
|
||||
int32_t tv_usec; /* microseconds within the second */
|
||||
};
|
||||
|
||||
struct os_timezone {
|
||||
int16_t tz_minuteswest; /* with respect to GMT */
|
||||
int16_t tz_dsttime; /* daylight savings time correction (if any) */
|
||||
};
|
||||
|
||||
#define os_timeradd(tvp, uvp, vvp) \
|
||||
do { \
|
||||
(vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \
|
||||
(vvp)->tv_usec = (tvp)->tv_usec + (uvp)->tv_usec; \
|
||||
if ((vvp)->tv_usec >= 1000000) { \
|
||||
(vvp)->tv_sec++; \
|
||||
(vvp)->tv_usec -= 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define os_timersub(tvp, uvp, vvp) \
|
||||
do { \
|
||||
(vvp)->tv_sec = (tvp)->tv_sec - (uvp)->tv_sec; \
|
||||
(vvp)->tv_usec = (tvp)->tv_usec - (uvp)->tv_usec; \
|
||||
if ((vvp)->tv_usec < 0) { \
|
||||
(vvp)->tv_sec--; \
|
||||
(vvp)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
int os_settimeofday(struct os_timeval *utctime, struct os_timezone *tz);
|
||||
int os_gettimeofday(struct os_timeval *utctime, struct os_timezone *tz);
|
||||
int64_t os_get_uptime_usec(void);
|
||||
int os_time_ms_to_ticks(uint32_t ms, uint32_t *out_ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_TIME_H */
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef OS_TRACE_API_H
|
||||
#define OS_TRACE_API_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/os.h"
|
||||
|
||||
#define OS_TRACE_ID_OFFSET (32u)
|
||||
|
||||
#define OS_TRACE_ID_EVQ_PUT (1u + OS_TRACE_ID_OFFSET)
|
||||
#define OS_TRACE_ID_EVQ_GET (2u + OS_TRACE_ID_OFFSET)
|
||||
#define OS_TRACE_ID_MUTEX_INIT (3u + OS_TRACE_ID_OFFSET)
|
||||
#define OS_TRACE_ID_MUTEX_RELEASE (4u + OS_TRACE_ID_OFFSET)
|
||||
#define OS_TRACE_ID_MUTEX_PEND (5u + OS_TRACE_ID_OFFSET)
|
||||
|
||||
#if MYNEWT_VAL(OS_SYSVIEW)
|
||||
void os_trace_enter_isr(void);
|
||||
void os_trace_exit_isr(void);
|
||||
void os_trace_exit_isr_to_scheduler(void);
|
||||
void os_trace_task_info(const struct os_task *p_task);
|
||||
void os_trace_task_create(uint32_t task_id);
|
||||
void os_trace_task_start_exec(uint32_t task_id);
|
||||
void os_trace_task_stop_exec(void);
|
||||
void os_trace_task_start_ready(uint32_t task_id);
|
||||
void os_trace_task_stop_ready(uint32_t task_id, unsigned reason);
|
||||
void os_trace_idle(void);
|
||||
|
||||
void os_trace_void(unsigned id);
|
||||
void os_trace_u32(unsigned id, uint32_t para0);
|
||||
void os_trace_u32x2(unsigned id, uint32_t para0, uint32_t para1);
|
||||
void os_trace_u32x3(unsigned id, uint32_t para0, uint32_t para1, uint32_t para2);
|
||||
void os_trace_u32x4(unsigned id, uint32_t para0, uint32_t para1, uint32_t para2, uint32_t para3);
|
||||
void os_trace_u32x5(unsigned id, uint32_t para0, uint32_t para1, uint32_t para2, uint32_t para3, uint32_t para4);
|
||||
void os_trace_enter_timer(uint32_t timer_id);
|
||||
void os_trace_exit_timer(void);
|
||||
|
||||
void os_trace_end_call(unsigned id);
|
||||
void os_trace_end_call_return_value(unsigned id, uint32_t return_value);
|
||||
|
||||
#else
|
||||
|
||||
static inline void os_trace_enter_isr(void){}
|
||||
static inline void os_trace_exit_isr(void){}
|
||||
static inline void os_trace_exit_isr_to_scheduler(void){}
|
||||
static inline void os_trace_task_info(const struct os_task *p_task){}
|
||||
static inline void os_trace_task_create(uint32_t task_id){}
|
||||
static inline void os_trace_task_start_exec(uint32_t task_id){}
|
||||
static inline void os_trace_task_stop_exec(void){}
|
||||
static inline void os_trace_task_start_ready(uint32_t task_id){}
|
||||
static inline void os_trace_task_stop_ready(uint32_t task_id, unsigned reason){}
|
||||
static inline void os_trace_idle(void){}
|
||||
static inline void os_trace_void(unsigned id){}
|
||||
static inline void os_trace_u32(unsigned id, uint32_t para0){}
|
||||
static inline void os_trace_u32x2(unsigned id, uint32_t para0, uint32_t para1){}
|
||||
static inline void os_trace_u32x3(unsigned id, uint32_t para0, uint32_t para1, uint32_t para2){}
|
||||
static inline void os_trace_u32x4(unsigned id, uint32_t para0, uint32_t para1, uint32_t para2, uint32_t para3){}
|
||||
static inline void os_trace_u32x5(unsigned id, uint32_t para0, uint32_t para1, uint32_t para2, uint32_t para3, uint32_t para4){}
|
||||
static inline void os_trace_enter_timer(uint32_t timer_id){}
|
||||
static inline void os_trace_exit_timer(void){}
|
||||
static inline void os_trace_end_call(unsigned id){}
|
||||
static inline void os_trace_end_call_return_value(unsigned id, uint32_t return_value){}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Executable
+522
@@ -0,0 +1,522 @@
|
||||
/*
|
||||
* Copyright (c) 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.7 2002/04/17 14:21:02 des Exp $
|
||||
*/
|
||||
|
||||
#ifndef _QUEUE_H_
|
||||
#define _QUEUE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file defines five types of data structures: singly-linked lists,
|
||||
* singly-linked tail queues, lists, tail queues, and circular queues.
|
||||
*
|
||||
* A singly-linked list is headed by a single forward pointer. The elements
|
||||
* are singly linked for minimum space and pointer manipulation overhead at
|
||||
* the expense of O(n) removal for arbitrary elements. New elements can be
|
||||
* added to the list after an existing element or at the head of the list.
|
||||
* Elements being removed from the head of the list should use the explicit
|
||||
* macro for this purpose for optimum efficiency. A singly-linked list may
|
||||
* only be traversed in the forward direction. Singly-linked lists are ideal
|
||||
* for applications with large datasets and few or no removals or for
|
||||
* implementing a LIFO queue.
|
||||
*
|
||||
* A singly-linked tail queue is headed by a pair of pointers, one to the
|
||||
* head of the list and the other to the tail of the list. The elements are
|
||||
* singly linked for minimum space and pointer manipulation overhead at the
|
||||
* expense of O(n) removal for arbitrary elements. New elements can be added
|
||||
* to the list after an existing element, at the head of the list, or at the
|
||||
* end of the list. Elements being removed from the head of the tail queue
|
||||
* should use the explicit macro for this purpose for optimum efficiency.
|
||||
* A singly-linked tail queue may only be traversed in the forward direction.
|
||||
* Singly-linked tail queues are ideal for applications with large datasets
|
||||
* and few or no removals or for implementing a FIFO queue.
|
||||
*
|
||||
* A list is headed by a single forward pointer (or an array of forward
|
||||
* pointers for a hash table header). The elements are doubly linked
|
||||
* so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before
|
||||
* or after an existing element or at the head of the list. A list
|
||||
* may only be traversed in the forward direction.
|
||||
*
|
||||
* A tail queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or
|
||||
* after an existing element, at the head of the list, or at the end of
|
||||
* the list. A tail queue may be traversed in either direction.
|
||||
*
|
||||
* A circle queue is headed by a pair of pointers, one to the head of the
|
||||
* list and the other to the tail of the list. The elements are doubly
|
||||
* linked so that an arbitrary element can be removed without a need to
|
||||
* traverse the list. New elements can be added to the list before or after
|
||||
* an existing element, at the head of the list, or at the end of the list.
|
||||
* A circle queue may be traversed in either direction, but has a more
|
||||
* complex end of list detection.
|
||||
*
|
||||
* For details on the use of these macros, see the queue(3) manual page.
|
||||
*
|
||||
*
|
||||
* SLIST LIST STAILQ TAILQ CIRCLEQ
|
||||
* _HEAD + + + + +
|
||||
* _HEAD_INITIALIZER + + + + +
|
||||
* _ENTRY + + + + +
|
||||
* _INIT + + + + +
|
||||
* _EMPTY + + + + +
|
||||
* _FIRST + + + + +
|
||||
* _NEXT + + + + +
|
||||
* _PREV - - - + +
|
||||
* _LAST - - + + +
|
||||
* _FOREACH + + + + +
|
||||
* _FOREACH_REVERSE - - - + +
|
||||
* _INSERT_HEAD + + + + +
|
||||
* _INSERT_BEFORE - + - + +
|
||||
* _INSERT_AFTER + + + + +
|
||||
* _INSERT_TAIL - - + + +
|
||||
* _REMOVE_HEAD + - + - -
|
||||
* _REMOVE + + + + +
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Singly-linked List declarations.
|
||||
*/
|
||||
#define SLIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *slh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define SLIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define SLIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *sle_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked List functions.
|
||||
*/
|
||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||
|
||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||
|
||||
#define SLIST_FOREACH(var, head, field) \
|
||||
for ((var) = SLIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = SLIST_NEXT((var), field))
|
||||
|
||||
#define SLIST_INIT(head) do { \
|
||||
SLIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||
SLIST_NEXT((slistelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||
SLIST_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||
|
||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||
if (SLIST_FIRST((head)) == (elm)) { \
|
||||
SLIST_REMOVE_HEAD((head), field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = SLIST_FIRST((head)); \
|
||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||
curelm = SLIST_NEXT(curelm, field); \
|
||||
SLIST_NEXT(curelm, field) = \
|
||||
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue declarations.
|
||||
*/
|
||||
#define STAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *stqh_first;/* first element */ \
|
||||
struct type **stqh_last;/* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).stqh_first }
|
||||
|
||||
#define STAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *stqe_next; /* next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Singly-linked Tail queue functions.
|
||||
*/
|
||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||
|
||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||
|
||||
#define STAILQ_FOREACH(var, head, field) \
|
||||
for((var) = STAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = STAILQ_NEXT((var), field))
|
||||
|
||||
#define STAILQ_INIT(head) do { \
|
||||
STAILQ_FIRST((head)) = NULL; \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
STAILQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
STAILQ_NEXT((elm), field) = NULL; \
|
||||
*(head)->stqh_last = (elm); \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_LAST(head, type, field) \
|
||||
(STAILQ_EMPTY(head) ? \
|
||||
NULL : \
|
||||
((struct type *) \
|
||||
((char *)((head)->stqh_last) - offsetof(struct type, field))))
|
||||
|
||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||
|
||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||
STAILQ_REMOVE_HEAD(head, field); \
|
||||
} \
|
||||
else { \
|
||||
struct type *curelm = STAILQ_FIRST((head)); \
|
||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||
curelm = STAILQ_NEXT(curelm, field); \
|
||||
if ((STAILQ_NEXT(curelm, field) = \
|
||||
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = \
|
||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define STAILQ_REMOVE_AFTER(head, elm, field) do { \
|
||||
if ((STAILQ_NEXT(elm, field) = \
|
||||
STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
|
||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* List declarations.
|
||||
*/
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *lh_first; /* first element */ \
|
||||
}
|
||||
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *le_next; /* next element */ \
|
||||
struct type **le_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* List functions.
|
||||
*/
|
||||
|
||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||
|
||||
#define LIST_FIRST(head) ((head)->lh_first)
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = LIST_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = LIST_NEXT((var), field))
|
||||
|
||||
#define LIST_INIT(head) do { \
|
||||
LIST_FIRST((head)) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||
&LIST_NEXT((elm), field); \
|
||||
LIST_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||
LIST_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.le_prev = (elm); \
|
||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
||||
LIST_FIRST((head)) = (elm); \
|
||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||
|
||||
#define LIST_REMOVE(elm, field) do { \
|
||||
if (LIST_NEXT((elm), field) != NULL) \
|
||||
LIST_NEXT((elm), field)->field.le_prev = \
|
||||
(elm)->field.le_prev; \
|
||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Tail queue declarations.
|
||||
*/
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *tqh_first; /* first element */ \
|
||||
struct type **tqh_last; /* addr of last next element */ \
|
||||
}
|
||||
|
||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||
{ NULL, &(head).tqh_first }
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *tqe_next; /* next element */ \
|
||||
struct type **tqe_prev; /* address of previous next element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Tail queue functions.
|
||||
*/
|
||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||
|
||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = TAILQ_FIRST((head)); \
|
||||
(var); \
|
||||
(var) = TAILQ_NEXT((var), field))
|
||||
|
||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||
for ((var) = TAILQ_LAST((head), headname); \
|
||||
(var); \
|
||||
(var) = TAILQ_PREV((var), headname, field))
|
||||
|
||||
#define TAILQ_INIT(head) do { \
|
||||
TAILQ_FIRST((head)) = NULL; \
|
||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_NEXT((listelm), field) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||
TAILQ_NEXT((elm), field) = (listelm); \
|
||||
*(listelm)->field.tqe_prev = (elm); \
|
||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||
&TAILQ_NEXT((elm), field); \
|
||||
else \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
TAILQ_FIRST((head)) = (elm); \
|
||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||
TAILQ_NEXT((elm), field) = NULL; \
|
||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||
*(head)->tqh_last = (elm); \
|
||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#define TAILQ_LAST(head, headname) \
|
||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||
|
||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||
|
||||
#define TAILQ_PREV(elm, headname, field) \
|
||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||
|
||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||
(elm)->field.tqe_prev; \
|
||||
else \
|
||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Circular queue declarations.
|
||||
*/
|
||||
#define CIRCLEQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *cqh_first; /* first element */ \
|
||||
struct type *cqh_last; /* last element */ \
|
||||
}
|
||||
|
||||
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||
{ (void *)&(head), (void *)&(head) }
|
||||
|
||||
#define CIRCLEQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *cqe_next; /* next element */ \
|
||||
struct type *cqe_prev; /* previous element */ \
|
||||
}
|
||||
|
||||
/*
|
||||
* Circular queue functions.
|
||||
*/
|
||||
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
||||
|
||||
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||
|
||||
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||
for ((var) = CIRCLEQ_FIRST((head)); \
|
||||
(var) != (void *)(head) || ((var) = NULL); \
|
||||
(var) = CIRCLEQ_NEXT((var), field))
|
||||
|
||||
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||
for ((var) = CIRCLEQ_LAST((head)); \
|
||||
(var) != (void *)(head) || ((var) = NULL); \
|
||||
(var) = CIRCLEQ_PREV((var), field))
|
||||
|
||||
#define CIRCLEQ_INIT(head) do { \
|
||||
CIRCLEQ_FIRST((head)) = (void *)(head); \
|
||||
CIRCLEQ_LAST((head)) = (void *)(head); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \
|
||||
CIRCLEQ_PREV((elm), field) = (listelm); \
|
||||
if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \
|
||||
CIRCLEQ_LAST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
|
||||
CIRCLEQ_NEXT((listelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = (listelm); \
|
||||
CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \
|
||||
if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \
|
||||
CIRCLEQ_FIRST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
|
||||
CIRCLEQ_PREV((listelm), field) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \
|
||||
CIRCLEQ_PREV((elm), field) = (void *)(head); \
|
||||
if (CIRCLEQ_LAST((head)) == (void *)(head)) \
|
||||
CIRCLEQ_LAST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
|
||||
CIRCLEQ_FIRST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||
CIRCLEQ_NEXT((elm), field) = (void *)(head); \
|
||||
CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \
|
||||
if (CIRCLEQ_FIRST((head)) == (void *)(head)) \
|
||||
CIRCLEQ_FIRST((head)) = (elm); \
|
||||
else \
|
||||
CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \
|
||||
CIRCLEQ_LAST((head)) = (elm); \
|
||||
} while (0)
|
||||
|
||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||
|
||||
#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
|
||||
|
||||
#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
|
||||
|
||||
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||
if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \
|
||||
CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \
|
||||
else \
|
||||
CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \
|
||||
CIRCLEQ_PREV((elm), field); \
|
||||
if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \
|
||||
CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
|
||||
else \
|
||||
CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \
|
||||
CIRCLEQ_NEXT((elm), field); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !_QUEUE_H_ */
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#ifndef __UTIL_STATS_H__
|
||||
#define __UTIL_STATS_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct stats_name_map {
|
||||
uint16_t snm_off;
|
||||
char *snm_name;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct stats_hdr {
|
||||
char *s_name;
|
||||
uint8_t s_size;
|
||||
uint8_t s_cnt;
|
||||
uint16_t s_pad1;
|
||||
#if MYNEWT_VAL(STATS_NAMES)
|
||||
const struct stats_name_map *s_map;
|
||||
int s_map_cnt;
|
||||
#endif
|
||||
STAILQ_ENTRY(stats_hdr) s_next;
|
||||
};
|
||||
|
||||
#define STATS_SECT_DECL(__name) \
|
||||
struct stats_ ## __name
|
||||
#define STATS_SECT_END };
|
||||
|
||||
#define STATS_SECT_START(__name) \
|
||||
STATS_SECT_DECL(__name) {
|
||||
#define STATS_SECT_VAR(__var)
|
||||
|
||||
#define STATS_HDR(__sectname)
|
||||
|
||||
#define STATS_SECT_ENTRY(__var)
|
||||
#define STATS_SECT_ENTRY16(__var)
|
||||
#define STATS_SECT_ENTRY32(__var)
|
||||
#define STATS_SECT_ENTRY64(__var)
|
||||
#define STATS_RESET(__var)
|
||||
|
||||
#define STATS_SIZE_INIT_PARMS(__sectvarname, __size) 0, 0
|
||||
|
||||
#define STATS_INC(__sectvarname, __var)
|
||||
#define STATS_INCN(__sectvarname, __var, __n)
|
||||
#define STATS_CLEAR(__sectvarname, __var)
|
||||
|
||||
#define STATS_NAME_START(__name)
|
||||
#define STATS_NAME(__name, __entry)
|
||||
#define STATS_NAME_END(__name)
|
||||
#define STATS_NAME_INIT_PARMS(__name) NULL, 0
|
||||
|
||||
#define stats_init(...) 0
|
||||
#define stats_register(name, shdr) 0
|
||||
#define stats_init_and_reg(...) 0
|
||||
#define stats_reset(shdr)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __UTIL_STATS_H__ */
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_SYSINIT_
|
||||
#define H_SYSINIT_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <assert.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
|
||||
#if MYNEWT_VAL(SPLIT_APPLICATION)
|
||||
#include "split/split.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern uint8_t sysinit_active;
|
||||
|
||||
void sysinit_start(void);
|
||||
void sysinit_end(void);
|
||||
|
||||
typedef void sysinit_panic_fn(const char *file, int line, const char *func,
|
||||
const char *expr, const char *msg);
|
||||
|
||||
extern sysinit_panic_fn *sysinit_panic_cb;
|
||||
|
||||
void sysinit_panic_set(sysinit_panic_fn *panic_fn);
|
||||
|
||||
#if MYNEWT_VAL(SYSINIT_PANIC_MESSAGE)
|
||||
|
||||
#if MYNEWT_VAL(SYSINIT_PANIC_FILE_LINE)
|
||||
#define SYSINIT_PANIC_MSG(msg) sysinit_panic_cb(__FILE__, __LINE__, 0, 0, msg)
|
||||
#else
|
||||
#define SYSINIT_PANIC_MSG(msg) sysinit_panic_cb(0, 0, 0, 0, msg)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#if MYNEWT_VAL(SYSINIT_PANIC_FILE_LINE)
|
||||
#define SYSINIT_PANIC_MSG(msg) sysinit_panic_cb(__FILE__, __LINE__, 0, 0, 0)
|
||||
#else
|
||||
#define SYSINIT_PANIC_MSG(msg) sysinit_panic_cb(0, 0, 0, 0, 0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#define SYSINIT_PANIC() SYSINIT_PANIC_MSG(NULL)
|
||||
|
||||
#define SYSINIT_PANIC_ASSERT_MSG(rc, msg) do \
|
||||
{ \
|
||||
if (!(rc)) { \
|
||||
SYSINIT_PANIC_MSG(msg); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SYSINIT_PANIC_ASSERT(rc) SYSINIT_PANIC_ASSERT_MSG(rc, NULL)
|
||||
|
||||
/**
|
||||
* Asserts that system initialization is in progress. This macro is used to
|
||||
* ensure packages don't get initialized a second time after system
|
||||
* initialization has completed.
|
||||
*/
|
||||
#if MYNEWT_VAL(SYSINIT_CONSTRAIN_INIT)
|
||||
#define SYSINIT_ASSERT_ACTIVE() assert(sysinit_active)
|
||||
#else
|
||||
#define SYSINIT_ASSERT_ACTIVE()
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(SPLIT_LOADER)
|
||||
|
||||
/*** System initialization for loader (first stage of split image). */
|
||||
void sysinit_loader(void);
|
||||
#define sysinit() do \
|
||||
{ \
|
||||
sysinit_start(); \
|
||||
sysinit_loader(); \
|
||||
sysinit_end(); \
|
||||
} while (0)
|
||||
|
||||
#elif MYNEWT_VAL(SPLIT_APPLICATION)
|
||||
|
||||
/*** System initialization for split-app (second stage of split image). */
|
||||
void sysinit_app(void);
|
||||
#define sysinit() do \
|
||||
{ \
|
||||
/* Record that a split app is running; imgmgt needs to know this. */ \
|
||||
split_app_active_set(1); \
|
||||
sysinit_start(); \
|
||||
sysinit_app(); \
|
||||
sysinit_end(); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
/*** System initialization for a unified image (no split). */
|
||||
void sysinit_app(void);
|
||||
#define sysinit() do \
|
||||
{ \
|
||||
sysinit_start(); \
|
||||
sysinit_app(); \
|
||||
sysinit_end(); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
#include "mem/mem.h"
|
||||
|
||||
/**
|
||||
* Mallocs a block of memory and initializes a mempool to use it.
|
||||
*
|
||||
* @param mempool The mempool to initialize.
|
||||
* @param num_blocks The total number of memory blocks in the
|
||||
* mempool.
|
||||
* @param block_size The size of each mempool entry.
|
||||
* @param name The name to give the mempool.
|
||||
* @param out_buf On success, this points to the malloced memory.
|
||||
* Pass NULL if you don't need this
|
||||
* information.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* OS_ENOMEM on malloc failure;
|
||||
* Other OS code on unexpected error.
|
||||
*/
|
||||
int
|
||||
mem_malloc_mempool(struct os_mempool *mempool, int num_blocks, int block_size,
|
||||
char *name, void **out_buf)
|
||||
{
|
||||
void *buf;
|
||||
int rc;
|
||||
|
||||
block_size = OS_ALIGN(block_size, OS_ALIGNMENT);
|
||||
|
||||
if (num_blocks > 0) {
|
||||
buf = malloc(OS_MEMPOOL_BYTES(num_blocks, block_size));
|
||||
if (buf == NULL) {
|
||||
return OS_ENOMEM;
|
||||
}
|
||||
} else {
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
rc = os_mempool_init(mempool, num_blocks, block_size, buf, name);
|
||||
if (rc != 0) {
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (out_buf != NULL) {
|
||||
*out_buf = buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mallocs a block of memory and initializes an mbuf pool to use it. The
|
||||
* specified block_size indicates the size of an mbuf acquired from the pool if
|
||||
* it does not contain a pkthdr.
|
||||
*
|
||||
* @param mempool The mempool to initialize.
|
||||
* @param mbuf_pool The mbuf pool to initialize.
|
||||
* @param num_blocks The total number of mbufs in the pool.
|
||||
* @param block_size The size of each mbuf.
|
||||
* @param name The name to give the mempool.
|
||||
* @param out_buf On success, this points to the malloced memory.
|
||||
* Pass NULL if you don't need this
|
||||
* information.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* OS_ENOMEM on malloc failure;
|
||||
* Other OS code on unexpected error.
|
||||
*/
|
||||
int
|
||||
mem_malloc_mbuf_pool(struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool, int num_blocks,
|
||||
int block_size, char *name,
|
||||
void **out_buf)
|
||||
{
|
||||
void *buf;
|
||||
int rc;
|
||||
|
||||
block_size = OS_ALIGN(block_size + sizeof (struct os_mbuf), OS_ALIGNMENT);
|
||||
|
||||
rc = mem_malloc_mempool(mempool, num_blocks, block_size, name, &buf);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = os_mbuf_pool_init(mbuf_pool, mempool, block_size, num_blocks);
|
||||
if (rc != 0) {
|
||||
free(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (out_buf != NULL) {
|
||||
*out_buf = buf;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mallocs a block of memory and initializes an mbuf pool to use it. The
|
||||
* specified block_size indicates the size of an mbuf acquired from the pool if
|
||||
* it contains a pkthdr.
|
||||
*
|
||||
* @param mempool The mempool to initialize.
|
||||
* @param mbuf_pool The mbuf pool to initialize.
|
||||
* @param num_blocks The total number of mbufs in the pool.
|
||||
* @param block_size The size of each mbuf.
|
||||
* @param name The name to give the mempool.
|
||||
* @param out_buf On success, this points to the malloced memory.
|
||||
* Pass NULL if you don't need this
|
||||
* information.
|
||||
*
|
||||
* @return 0 on success;
|
||||
* OS_ENOMEM on malloc failure;
|
||||
* Other OS code on unexpected error.
|
||||
*/
|
||||
int
|
||||
mem_malloc_mbufpkt_pool(struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool, int num_blocks,
|
||||
int block_size, char *name,
|
||||
void **out_buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = mem_malloc_mbuf_pool(mempool, mbuf_pool, num_blocks,
|
||||
block_size + sizeof (struct os_mbuf_pkthdr),
|
||||
name, out_buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
mem_init_mbuf_pool(void *mem, struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool, int num_blocks,
|
||||
int block_size, char *name)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_mempool_init(mempool, num_blocks, block_size, mem, name);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = os_mbuf_pool_init(mbuf_pool, mempool, block_size, num_blocks);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Splits an appropriately-sized fragment from the front of an mbuf chain, as
|
||||
* neeeded. If the length of the mbuf chain greater than specified maximum
|
||||
* fragment size, a new mbuf is allocated, and data is moved from the source
|
||||
* mbuf to the new mbuf. If the mbuf chain is small enough to fit in a single
|
||||
* fragment, the source mbuf itself is returned unmodified, and the suplied
|
||||
* pointer is set to NULL.
|
||||
*
|
||||
* This function is expected to be called in a loop until the entire mbuf chain
|
||||
* has been consumed. For example:
|
||||
*
|
||||
* struct os_mbuf *frag;
|
||||
* struct os_mbuf *rsp;
|
||||
* // [...]
|
||||
* while (rsp != NULL) {
|
||||
* frag = mem_split_frag(&rsp, get_mtu(), frag_alloc, NULL);
|
||||
* if (frag == NULL) {
|
||||
* os_mbuf_free_chain(rsp);
|
||||
* return SYS_ENOMEM;
|
||||
* }
|
||||
* send_packet(frag)
|
||||
* }
|
||||
*
|
||||
* @param om The packet to fragment. Upon fragmentation,
|
||||
* this mbuf is adjusted such that the
|
||||
* fragment data is removed. If the packet
|
||||
* constitutes a single fragment, this gets
|
||||
* set to NULL on success.
|
||||
* @param max_frag_sz The maximum payload size of a fragment.
|
||||
* Typically this is the MTU of the
|
||||
* connection.
|
||||
* @param alloc_cb Points to a function that allocates an mbuf to
|
||||
* hold a fragment. This function gets called
|
||||
* before the source mbuf chain is modified,
|
||||
* so it can safely inspect it.
|
||||
* @param cb_arg Generic parameter that gets passed to the
|
||||
* callback function.
|
||||
*
|
||||
* @return The next fragment to send on success;
|
||||
* NULL on failure.
|
||||
*/
|
||||
struct os_mbuf *
|
||||
mem_split_frag(struct os_mbuf **om, uint16_t max_frag_sz,
|
||||
mem_frag_alloc_fn *alloc_cb, void *cb_arg)
|
||||
{
|
||||
struct os_mbuf *frag;
|
||||
int rc;
|
||||
|
||||
if (OS_MBUF_PKTLEN(*om) <= max_frag_sz) {
|
||||
/* Final fragment. */
|
||||
frag = *om;
|
||||
*om = NULL;
|
||||
return frag;
|
||||
}
|
||||
|
||||
/* Packet needs to be split. Allocate a new buffer for the fragment. */
|
||||
frag = alloc_cb(max_frag_sz, cb_arg);
|
||||
if (frag == NULL) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Move data from the front of the packet into the fragment mbuf. */
|
||||
rc = os_mbuf_appendfrom(frag, *om, 0, max_frag_sz);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
os_mbuf_adj(*om, max_frag_sz);
|
||||
|
||||
/* Free unused portion of of source mbuf chain, if possible. */
|
||||
*om = os_mbuf_trim_front(*om);
|
||||
|
||||
return frag;
|
||||
|
||||
err:
|
||||
os_mbuf_free_chain(frag);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 <stddef.h>
|
||||
#include "os/os.h"
|
||||
#include "sysinit/sysinit.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
#include "services/gatt/ble_svc_gatt.h"
|
||||
#include "services/ans/ble_svc_ans.h"
|
||||
#include "services/ias/ble_svc_ias.h"
|
||||
#include "services/lls/ble_svc_lls.h"
|
||||
#include "services/tps/ble_svc_tps.h"
|
||||
#include "controller/ble_ll.h"
|
||||
|
||||
void
|
||||
nimble_init(void)
|
||||
{
|
||||
void os_msys_init(void);
|
||||
void ble_hci_ram_pkg_init(void);
|
||||
void ble_store_ram_init(void);
|
||||
|
||||
sysinit_start();
|
||||
os_msys_init();
|
||||
ble_hci_ram_pkg_init();
|
||||
ble_hs_init();
|
||||
ble_ll_init();
|
||||
ble_svc_gap_init();
|
||||
ble_svc_gatt_init();
|
||||
ble_svc_ans_init();
|
||||
ble_svc_ias_init();
|
||||
ble_svc_lls_init();
|
||||
ble_svc_tps_init();
|
||||
ble_store_ram_init();
|
||||
sysinit_end();
|
||||
}
|
||||
|
||||
void
|
||||
nimble_run(void)
|
||||
{
|
||||
while (1) {
|
||||
struct os_event *ev;
|
||||
|
||||
ev = os_eventq_get(os_eventq_dflt_get());
|
||||
assert(ev->ev_cb != NULL);
|
||||
|
||||
ev->ev_cb(ev);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* 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/endian.h"
|
||||
|
||||
void
|
||||
put_le16(void *buf, uint16_t x)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
|
||||
u8ptr = buf;
|
||||
u8ptr[0] = (uint8_t)x;
|
||||
u8ptr[1] = (uint8_t)(x >> 8);
|
||||
}
|
||||
|
||||
void
|
||||
put_le32(void *buf, uint32_t x)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
|
||||
u8ptr = buf;
|
||||
u8ptr[0] = (uint8_t)x;
|
||||
u8ptr[1] = (uint8_t)(x >> 8);
|
||||
u8ptr[2] = (uint8_t)(x >> 16);
|
||||
u8ptr[3] = (uint8_t)(x >> 24);
|
||||
}
|
||||
|
||||
void
|
||||
put_le64(void *buf, uint64_t x)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
|
||||
u8ptr = buf;
|
||||
u8ptr[0] = (uint8_t)x;
|
||||
u8ptr[1] = (uint8_t)(x >> 8);
|
||||
u8ptr[2] = (uint8_t)(x >> 16);
|
||||
u8ptr[3] = (uint8_t)(x >> 24);
|
||||
u8ptr[4] = (uint8_t)(x >> 32);
|
||||
u8ptr[5] = (uint8_t)(x >> 40);
|
||||
u8ptr[6] = (uint8_t)(x >> 48);
|
||||
u8ptr[7] = (uint8_t)(x >> 56);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
get_le16(const void *buf)
|
||||
{
|
||||
const uint8_t *u8ptr;
|
||||
uint16_t x;
|
||||
|
||||
u8ptr = buf;
|
||||
x = u8ptr[0];
|
||||
x |= (uint16_t)u8ptr[1] << 8;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
get_le32(const void *buf)
|
||||
{
|
||||
const uint8_t *u8ptr;
|
||||
uint32_t x;
|
||||
|
||||
u8ptr = buf;
|
||||
x = u8ptr[0];
|
||||
x |= (uint32_t)u8ptr[1] << 8;
|
||||
x |= (uint32_t)u8ptr[2] << 16;
|
||||
x |= (uint32_t)u8ptr[3] << 24;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
get_le64(const void *buf)
|
||||
{
|
||||
const uint8_t *u8ptr;
|
||||
uint64_t x;
|
||||
|
||||
u8ptr = buf;
|
||||
x = u8ptr[0];
|
||||
x |= (uint64_t)u8ptr[1] << 8;
|
||||
x |= (uint64_t)u8ptr[2] << 16;
|
||||
x |= (uint64_t)u8ptr[3] << 24;
|
||||
x |= (uint64_t)u8ptr[4] << 32;
|
||||
x |= (uint64_t)u8ptr[5] << 40;
|
||||
x |= (uint64_t)u8ptr[6] << 48;
|
||||
x |= (uint64_t)u8ptr[7] << 56;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
void
|
||||
put_be16(void *buf, uint16_t x)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
|
||||
u8ptr = buf;
|
||||
u8ptr[0] = (uint8_t)(x >> 8);
|
||||
u8ptr[1] = (uint8_t)x;
|
||||
}
|
||||
|
||||
void
|
||||
put_be32(void *buf, uint32_t x)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
|
||||
u8ptr = buf;
|
||||
u8ptr[0] = (uint8_t)(x >> 24);
|
||||
u8ptr[1] = (uint8_t)(x >> 16);
|
||||
u8ptr[2] = (uint8_t)(x >> 8);
|
||||
u8ptr[3] = (uint8_t)x;
|
||||
}
|
||||
|
||||
void
|
||||
put_be64(void *buf, uint64_t x)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
|
||||
u8ptr = buf;
|
||||
u8ptr[0] = (uint8_t)(x >> 56);
|
||||
u8ptr[1] = (uint8_t)(x >> 48);
|
||||
u8ptr[2] = (uint8_t)(x >> 40);
|
||||
u8ptr[3] = (uint8_t)(x >> 32);
|
||||
u8ptr[4] = (uint8_t)(x >> 24);
|
||||
u8ptr[5] = (uint8_t)(x >> 16);
|
||||
u8ptr[6] = (uint8_t)(x >> 8);
|
||||
u8ptr[7] = (uint8_t)x;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
get_be16(const void *buf)
|
||||
{
|
||||
const uint8_t *u8ptr;
|
||||
uint16_t x;
|
||||
|
||||
u8ptr = buf;
|
||||
x = (uint16_t)u8ptr[0] << 8;
|
||||
x |= u8ptr[1];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
get_be32(const void *buf)
|
||||
{
|
||||
const uint8_t *u8ptr;
|
||||
uint32_t x;
|
||||
|
||||
u8ptr = buf;
|
||||
x = (uint32_t)u8ptr[0] << 24;
|
||||
x |= (uint32_t)u8ptr[1] << 16;
|
||||
x |= (uint32_t)u8ptr[2] << 8;
|
||||
x |= u8ptr[3];
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
get_be64(const void *buf)
|
||||
{
|
||||
const uint8_t *u8ptr;
|
||||
uint64_t x;
|
||||
|
||||
u8ptr = buf;
|
||||
x = (uint64_t)u8ptr[0] << 56;
|
||||
x |= (uint64_t)u8ptr[1] << 48;
|
||||
x |= (uint64_t)u8ptr[2] << 40;
|
||||
x |= (uint64_t)u8ptr[3] << 32;
|
||||
x |= (uint64_t)u8ptr[4] << 24;
|
||||
x |= (uint64_t)u8ptr[5] << 16;
|
||||
x |= (uint64_t)u8ptr[6] << 8;
|
||||
x |= u8ptr[7];
|
||||
|
||||
return x;
|
||||
}
|
||||
void
|
||||
swap_in_place(void *buf, int len)
|
||||
{
|
||||
uint8_t *u8ptr;
|
||||
uint8_t tmp;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
u8ptr = buf;
|
||||
|
||||
for (i = 0, j = len - 1; i < j; i++, j--) {
|
||||
tmp = u8ptr[i];
|
||||
|
||||
u8ptr[i] = u8ptr[j];
|
||||
u8ptr[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* swap octets */
|
||||
void
|
||||
swap_buf(uint8_t *dst, const uint8_t *src, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
dst[len - 1 - i] = src[i];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* 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 "sysinit/sysinit.h"
|
||||
#include "os/os.h"
|
||||
#include "os/queue.h"
|
||||
#include "os/os_dev.h"
|
||||
#include "os/os_trace_api.h"
|
||||
#include "hal/hal_os_tick.h"
|
||||
#include "hal/hal_bsp.h"
|
||||
#include "hal/hal_watchdog.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "../os/os_priv.h"
|
||||
|
||||
/**
|
||||
* @defgroup OSKernel Operating System Kernel
|
||||
* @brief This section contains documentation for the core operating system kernel
|
||||
* of Apache Mynewt.
|
||||
* @{
|
||||
* @addtogroup OSGeneral General Functions
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct os_task g_idle_task;
|
||||
os_stack_t g_idle_task_stack[OS_STACK_ALIGN(OS_IDLE_STACK_SIZE)];
|
||||
|
||||
uint32_t g_os_idle_ctr;
|
||||
|
||||
static struct os_task os_main_task;
|
||||
static os_stack_t os_main_stack[OS_STACK_ALIGN(OS_MAIN_STACK_SIZE)];
|
||||
|
||||
/* Default zero. Set by the architecture specific code when os is started.
|
||||
*/
|
||||
int g_os_started;
|
||||
|
||||
#ifdef ARCH_sim
|
||||
#define MIN_IDLE_TICKS 1
|
||||
#else
|
||||
#define MIN_IDLE_TICKS (100 * OS_TICKS_PER_SEC / 1000) /* 100 msec */
|
||||
#endif
|
||||
#define MAX_IDLE_TICKS (600 * OS_TICKS_PER_SEC) /* 10 minutes */
|
||||
|
||||
|
||||
/**
|
||||
* Idle operating system task, runs when no other tasks are running.
|
||||
* The idle task operates in tickless mode, which means it looks for
|
||||
* the next time an event in the system needs to run, and then tells
|
||||
* the architecture specific functions to sleep until that time.
|
||||
*
|
||||
* @param arg unused
|
||||
*/
|
||||
void
|
||||
os_idle_task(void *arg)
|
||||
{
|
||||
os_sr_t sr;
|
||||
os_time_t now;
|
||||
os_time_t iticks, sticks, cticks;
|
||||
os_time_t sanity_last;
|
||||
os_time_t sanity_itvl_ticks;
|
||||
|
||||
sanity_itvl_ticks = (MYNEWT_VAL(SANITY_INTERVAL) * OS_TICKS_PER_SEC) / 1000;
|
||||
sanity_last = 0;
|
||||
|
||||
hal_watchdog_tickle();
|
||||
|
||||
while (1) {
|
||||
++g_os_idle_ctr;
|
||||
|
||||
now = os_time_get();
|
||||
if (OS_TIME_TICK_GT(now, sanity_last + sanity_itvl_ticks)) {
|
||||
os_sanity_run();
|
||||
/* Tickle the watchdog after successfully running sanity */
|
||||
hal_watchdog_tickle();
|
||||
sanity_last = now;
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
now = os_time_get();
|
||||
sticks = os_sched_wakeup_ticks(now);
|
||||
cticks = os_callout_wakeup_ticks(now);
|
||||
iticks = min(sticks, cticks);
|
||||
/* Wakeup in time to run sanity as well from the idle context,
|
||||
* as the idle task does not schedule itself.
|
||||
*/
|
||||
iticks = min(iticks, ((sanity_last + sanity_itvl_ticks) - now));
|
||||
|
||||
if (iticks < MIN_IDLE_TICKS) {
|
||||
iticks = 0;
|
||||
} else if (iticks > MAX_IDLE_TICKS) {
|
||||
iticks = MAX_IDLE_TICKS;
|
||||
} else {
|
||||
/* NOTHING */
|
||||
}
|
||||
/* Tell the architecture specific support to put the processor to sleep
|
||||
* for 'n' ticks.
|
||||
*/
|
||||
|
||||
os_trace_idle();
|
||||
os_tick_idle(iticks);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Has the operating system started.
|
||||
*
|
||||
* @return 1 if the operating system has started, 0 if it hasn't
|
||||
*/
|
||||
int
|
||||
os_started(void)
|
||||
{
|
||||
return (g_os_started);
|
||||
}
|
||||
|
||||
static void
|
||||
os_main(void *arg)
|
||||
{
|
||||
int (*fn)(int argc, char **argv) = arg;
|
||||
|
||||
#if !MYNEWT_VAL(SELFTEST)
|
||||
fn(0, NULL);
|
||||
#else
|
||||
(void)fn;
|
||||
while (1) {
|
||||
os_eventq_run(os_eventq_dflt_get());
|
||||
}
|
||||
#endif
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void
|
||||
os_init_idle_task(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_task_init(&g_idle_task, "idle", os_idle_task, NULL,
|
||||
OS_IDLE_PRIO, OS_WAIT_FOREVER, g_idle_task_stack,
|
||||
OS_STACK_ALIGN(OS_IDLE_STACK_SIZE));
|
||||
assert(rc == 0);
|
||||
|
||||
/* Initialize sanity */
|
||||
rc = os_sanity_init();
|
||||
assert(rc == 0);
|
||||
|
||||
assert(MYNEWT_VAL(WATCHDOG_INTERVAL) - 200 > MYNEWT_VAL(SANITY_INTERVAL));
|
||||
|
||||
rc = hal_watchdog_init(MYNEWT_VAL(WATCHDOG_INTERVAL));
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the operating system, calls into the architecture specific
|
||||
* support to initialize the operating system.
|
||||
*/
|
||||
void
|
||||
os_init(int (*main_fn)(int argc, char **arg))
|
||||
{
|
||||
os_error_t err;
|
||||
|
||||
TAILQ_INIT(&g_callout_list);
|
||||
STAILQ_INIT(&g_os_task_list);
|
||||
os_eventq_init(os_eventq_dflt_get());
|
||||
|
||||
/* Initialize device list. */
|
||||
os_dev_reset();
|
||||
|
||||
err = os_arch_os_init();
|
||||
assert(err == OS_OK);
|
||||
|
||||
if (main_fn) {
|
||||
err = os_task_init(&os_main_task, "main", os_main, main_fn,
|
||||
OS_MAIN_TASK_PRIO, OS_WAIT_FOREVER, os_main_stack,
|
||||
OS_STACK_ALIGN(OS_MAIN_STACK_SIZE));
|
||||
assert(err == 0);
|
||||
}
|
||||
/* Call bsp related OS initializations */
|
||||
hal_bsp_init();
|
||||
|
||||
err = (os_error_t) os_dev_initialize_all(OS_DEV_INIT_PRIMARY);
|
||||
assert(err == OS_OK);
|
||||
|
||||
err = (os_error_t) os_dev_initialize_all(OS_DEV_INIT_SECONDARY);
|
||||
assert(err == OS_OK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the operating system, calls into the architecture specific support
|
||||
* to start the operating system.
|
||||
*/
|
||||
void
|
||||
os_start(void)
|
||||
{
|
||||
#if MYNEWT_VAL(OS_SCHEDULING)
|
||||
os_error_t err;
|
||||
|
||||
/* Enable the watchdog prior to starting the OS */
|
||||
hal_watchdog_enable();
|
||||
|
||||
err = os_arch_os_start();
|
||||
assert(err == OS_OK);
|
||||
#else
|
||||
assert(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
os_pkg_init(void)
|
||||
{
|
||||
os_error_t err;
|
||||
|
||||
/* Ensure this function only gets called by sysinit. */
|
||||
SYSINIT_ASSERT_ACTIVE();
|
||||
|
||||
err = os_dev_initialize_all(OS_DEV_INIT_KERNEL);
|
||||
assert(err == OS_OK);
|
||||
|
||||
os_msys_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* }@ General OS functions
|
||||
* }@ OS Kernel
|
||||
*/
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "../os/os_priv.h"
|
||||
#include "os/os.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSCallouts Event Timers (Callouts)
|
||||
* @{
|
||||
*/
|
||||
struct os_callout_list g_callout_list;
|
||||
|
||||
/**
|
||||
* Initialize a callout.
|
||||
*
|
||||
* Callouts are used to schedule events in the future onto a task's event
|
||||
* queue. Callout timers are scheduled using the os_callout_reset()
|
||||
* function. When the timer expires, an event is posted to the event
|
||||
* queue specified in os_callout_init(). The event argument given here
|
||||
* is posted in the ev_arg field of that event.
|
||||
*
|
||||
* @param c The callout to initialize
|
||||
* @param evq The event queue to post an OS_EVENT_T_TIMER event to
|
||||
* @param timo_func The function to call on this callout for the host task
|
||||
* used to provide multiple timer events to a task
|
||||
* (this can be NULL.)
|
||||
* @param ev_arg The argument to provide to the event when posting the
|
||||
* timer.
|
||||
*/
|
||||
void os_callout_init(struct os_callout *c, struct os_eventq *evq,
|
||||
os_event_fn *ev_cb, void *ev_arg)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
c->c_ev.ev_cb = ev_cb;
|
||||
c->c_ev.ev_arg = ev_arg;
|
||||
c->c_evq = evq;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the callout from firing off, any pending events will be cleared.
|
||||
*
|
||||
* @param c The callout to stop
|
||||
*/
|
||||
void
|
||||
os_callout_stop(struct os_callout *c)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
if (os_callout_queued(c)) {
|
||||
TAILQ_REMOVE(&g_callout_list, c, c_next);
|
||||
c->c_next.tqe_prev = NULL;
|
||||
}
|
||||
|
||||
if (c->c_evq) {
|
||||
os_eventq_remove(c->c_evq, &c->c_ev);
|
||||
}
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the callout to fire off in 'ticks' ticks.
|
||||
*
|
||||
* @param c The callout to reset
|
||||
* @param ticks The number of ticks to wait before posting an event
|
||||
*
|
||||
* @return 0 on success, non-zero on failure
|
||||
*/
|
||||
int
|
||||
os_callout_reset(struct os_callout *c, int32_t ticks)
|
||||
{
|
||||
struct os_callout *entry;
|
||||
os_sr_t sr;
|
||||
int rc;
|
||||
|
||||
if (ticks < 0) {
|
||||
rc = OS_EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
os_callout_stop(c);
|
||||
|
||||
if (ticks == 0) {
|
||||
ticks = 1;
|
||||
}
|
||||
|
||||
c->c_ticks = os_time_get() + ticks;
|
||||
|
||||
entry = NULL;
|
||||
TAILQ_FOREACH(entry, &g_callout_list, c_next) {
|
||||
if (OS_TIME_TICK_LT(c->c_ticks, entry->c_ticks)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (entry) {
|
||||
TAILQ_INSERT_BEFORE(entry, c, c_next);
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&g_callout_list, c, c_next);
|
||||
}
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function is called by the OS in the time tick. It searches the list
|
||||
* of callouts, and sees if any of them are ready to run. If they are ready
|
||||
* to run, it posts an event for each callout that's ready to run,
|
||||
* to the event queue provided to os_callout_init().
|
||||
*/
|
||||
void
|
||||
os_callout_tick(void)
|
||||
{
|
||||
os_sr_t sr;
|
||||
struct os_callout *c;
|
||||
uint32_t now;
|
||||
|
||||
now = os_time_get();
|
||||
|
||||
while (1) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
c = TAILQ_FIRST(&g_callout_list);
|
||||
if (c) {
|
||||
if (OS_TIME_TICK_GEQ(now, c->c_ticks)) {
|
||||
TAILQ_REMOVE(&g_callout_list, c, c_next);
|
||||
c->c_next.tqe_prev = NULL;
|
||||
} else {
|
||||
c = NULL;
|
||||
}
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
if (c) {
|
||||
if (c->c_evq) {
|
||||
os_eventq_put(c->c_evq, &c->c_ev);
|
||||
} else {
|
||||
c->c_ev.ev_cb(&c->c_ev);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of ticks to the first pending callout. If there are no
|
||||
* pending callouts then return OS_TIMEOUT_NEVER instead.
|
||||
*
|
||||
* @param now The time now
|
||||
*
|
||||
* @return Number of ticks to first pending callout
|
||||
*/
|
||||
os_time_t
|
||||
os_callout_wakeup_ticks(os_time_t now)
|
||||
{
|
||||
os_time_t rt;
|
||||
struct os_callout *c;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
c = TAILQ_FIRST(&g_callout_list);
|
||||
if (c != NULL) {
|
||||
if (OS_TIME_TICK_GEQ(c->c_ticks, now)) {
|
||||
rt = c->c_ticks - now;
|
||||
} else {
|
||||
rt = 0; /* callout time is in the past */
|
||||
}
|
||||
} else {
|
||||
rt = OS_TIMEOUT_NEVER;
|
||||
}
|
||||
|
||||
return (rt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the number of ticks which remains to callout..
|
||||
*
|
||||
* @param c callout
|
||||
* @param now The time now
|
||||
*
|
||||
* @return Number of ticks to first pending callout
|
||||
*/
|
||||
os_time_t os_callout_remaining_ticks(struct os_callout *c, os_time_t now)
|
||||
{
|
||||
os_time_t rt;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
if (OS_TIME_TICK_GEQ(c->c_ticks, now)) {
|
||||
rt = c->c_ticks - now;
|
||||
} else {
|
||||
rt = 0; /* callout time is in the past */
|
||||
}
|
||||
|
||||
return rt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} Callout Timers
|
||||
* @} OS Kernel
|
||||
*/
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include "os/os.h"
|
||||
#include "os/os_cputime.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel Operating System Kernel
|
||||
* @{
|
||||
* @defgroup OSCPUTime High Resolution Timers
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if defined(OS_CPUTIME_FREQ_HIGH)
|
||||
struct os_cputime_data g_os_cputime;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* os cputime init
|
||||
*
|
||||
* Initialize the cputime module. This must be called after os_init is called
|
||||
* and before any other timer API are used. This should be called only once
|
||||
* and should be called before the hardware timer is used.
|
||||
*
|
||||
* @param clock_freq The desired cputime frequency, in hertz (Hz).
|
||||
*
|
||||
* @return int 0 on success; -1 on error.
|
||||
*/
|
||||
int
|
||||
os_cputime_init(uint32_t clock_freq)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Set the ticks per microsecond. */
|
||||
#if defined(OS_CPUTIME_FREQ_HIGH)
|
||||
g_os_cputime.ticks_per_usec = clock_freq / 1000000U;
|
||||
#endif
|
||||
rc = hal_timer_config(MYNEWT_VAL(OS_CPUTIME_TIMER_NUM), clock_freq);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime delay ticks
|
||||
*
|
||||
* Wait until the number of ticks has elapsed. This is a blocking delay.
|
||||
*
|
||||
* @param ticks The number of ticks to wait.
|
||||
*/
|
||||
void
|
||||
os_cputime_delay_ticks(uint32_t ticks)
|
||||
{
|
||||
uint32_t until;
|
||||
|
||||
until = os_cputime_get32() + ticks;
|
||||
while ((int32_t)(os_cputime_get32() - until) < 0) {
|
||||
/* Loop here till finished */
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(OS_CPUTIME_FREQ_PWR2)
|
||||
/**
|
||||
* os cputime delay nsecs
|
||||
*
|
||||
* Wait until 'nsecs' nanoseconds has elapsed. This is a blocking delay.
|
||||
*
|
||||
* @param nsecs The number of nanoseconds to wait.
|
||||
*/
|
||||
void
|
||||
os_cputime_delay_nsecs(uint32_t nsecs)
|
||||
{
|
||||
uint32_t ticks;
|
||||
|
||||
ticks = os_cputime_nsecs_to_ticks(nsecs);
|
||||
os_cputime_delay_ticks(ticks);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* os cputime delay usecs
|
||||
*
|
||||
* Wait until 'usecs' microseconds has elapsed. This is a blocking delay.
|
||||
*
|
||||
* @param usecs The number of usecs to wait.
|
||||
*/
|
||||
void
|
||||
os_cputime_delay_usecs(uint32_t usecs)
|
||||
{
|
||||
uint32_t ticks;
|
||||
|
||||
ticks = os_cputime_usecs_to_ticks(usecs);
|
||||
os_cputime_delay_ticks(ticks);
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime timer init
|
||||
*
|
||||
* @param timer The timer to initialize. Cannot be NULL.
|
||||
* @param fp The timer callback function. Cannot be NULL.
|
||||
* @param arg Pointer to data object to pass to timer.
|
||||
*/
|
||||
void
|
||||
os_cputime_timer_init(struct hal_timer *timer, hal_timer_cb fp, void *arg)
|
||||
{
|
||||
assert(timer != NULL);
|
||||
assert(fp != NULL);
|
||||
|
||||
hal_timer_set_cb(MYNEWT_VAL(OS_CPUTIME_TIMER_NUM), timer, fp, arg);
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime timer start
|
||||
*
|
||||
* Start a cputimer that will expire at 'cputime'. If cputime has already
|
||||
* passed, the timer callback will still be called (at interrupt context).
|
||||
*
|
||||
* NOTE: This must be called when the timer is stopped.
|
||||
*
|
||||
* @param timer Pointer to timer to start. Cannot be NULL.
|
||||
* @param cputime The cputime at which the timer should expire.
|
||||
*
|
||||
* @return int 0 on success; EINVAL if timer already started or timer struct
|
||||
* invalid
|
||||
*
|
||||
*/
|
||||
int
|
||||
os_cputime_timer_start(struct hal_timer *timer, uint32_t cputime)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = hal_timer_start_at(timer, cputime);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputimer timer relative
|
||||
*
|
||||
* Sets a cpu timer that will expire 'usecs' microseconds from the current
|
||||
* cputime.
|
||||
*
|
||||
* NOTE: This must be called when the timer is stopped.
|
||||
*
|
||||
* @param timer Pointer to timer. Cannot be NULL.
|
||||
* @param usecs The number of usecs from now at which the timer will expire.
|
||||
*
|
||||
* @return int 0 on success; EINVAL if timer already started or timer struct
|
||||
* invalid
|
||||
*/
|
||||
int
|
||||
os_cputime_timer_relative(struct hal_timer *timer, uint32_t usecs)
|
||||
{
|
||||
int rc;
|
||||
uint32_t cputime;
|
||||
|
||||
assert(timer != NULL);
|
||||
|
||||
cputime = os_cputime_get32() + os_cputime_usecs_to_ticks(usecs);
|
||||
rc = hal_timer_start_at(timer, cputime);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime timer stop
|
||||
*
|
||||
* Stops a cputimer from running. The timer is removed from the timer queue
|
||||
* and interrupts are disabled if no timers are left on the queue. Can be
|
||||
* called even if timer is not running.
|
||||
*
|
||||
* @param timer Pointer to cputimer to stop. Cannot be NULL.
|
||||
*/
|
||||
void
|
||||
os_cputime_timer_stop(struct hal_timer *timer)
|
||||
{
|
||||
hal_timer_stop(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime get32
|
||||
*
|
||||
* Returns current value of cputime.
|
||||
*
|
||||
* @return uint32_t cputime
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_get32(void)
|
||||
{
|
||||
uint32_t cpu_time;
|
||||
|
||||
cpu_time = hal_timer_read(MYNEWT_VAL(OS_CPUTIME_TIMER_NUM));
|
||||
return cpu_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSCPUTime
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "os/os_cputime.h"
|
||||
|
||||
/**
|
||||
* This module implements cputime functionality for timers whose frequency is
|
||||
* exactly 1 MHz.
|
||||
*/
|
||||
|
||||
#if defined(OS_CPUTIME_FREQ_1MHZ)
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel Operating System Kernel
|
||||
* @{
|
||||
* @defgroup OSCPUTime High Resolution Timers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* os cputime nsecs to ticks
|
||||
*
|
||||
* Converts the given number of nanoseconds into cputime ticks.
|
||||
*
|
||||
* @param usecs The number of nanoseconds to convert to ticks
|
||||
*
|
||||
* @return uint32_t The number of ticks corresponding to 'nsecs'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_nsecs_to_ticks(uint32_t nsecs)
|
||||
{
|
||||
return (nsecs + 999) / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime ticks to nsecs
|
||||
*
|
||||
* Convert the given number of ticks into nanoseconds.
|
||||
*
|
||||
* @param ticks The number of ticks to convert to nanoseconds.
|
||||
*
|
||||
* @return uint32_t The number of nanoseconds corresponding to 'ticks'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_ticks_to_nsecs(uint32_t ticks)
|
||||
{
|
||||
return ticks * 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSCPUTime
|
||||
* @} OSKernel
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,84 @@
|
||||
#include "os/os_cputime.h"
|
||||
|
||||
/**
|
||||
* This module implements cputime functionality for timers whose frequency is
|
||||
* greater than 1 MHz.
|
||||
*/
|
||||
|
||||
#if defined(OS_CPUTIME_FREQ_HIGH)
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel Operating System Kernel
|
||||
* @{
|
||||
* @defgroup OSCPUTime High Resolution Timers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* os cputime usecs to ticks
|
||||
*
|
||||
* Converts the given number of microseconds into cputime ticks.
|
||||
*
|
||||
* @param usecs The number of microseconds to convert to ticks
|
||||
*
|
||||
* @return uint32_t The number of ticks corresponding to 'usecs'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_usecs_to_ticks(uint32_t usecs)
|
||||
{
|
||||
return usecs * g_os_cputime.ticks_per_usec;
|
||||
}
|
||||
|
||||
/**
|
||||
* cputime ticks to usecs
|
||||
*
|
||||
* Convert the given number of ticks into microseconds.
|
||||
*
|
||||
* @param ticks The number of ticks to convert to microseconds.
|
||||
*
|
||||
* @return uint32_t The number of microseconds corresponding to 'ticks'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_ticks_to_usecs(uint32_t ticks)
|
||||
{
|
||||
return (ticks + g_os_cputime.ticks_per_usec - 1) /
|
||||
g_os_cputime.ticks_per_usec;
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime nsecs to ticks
|
||||
*
|
||||
* Converts the given number of nanoseconds into cputime ticks.
|
||||
*
|
||||
* @param usecs The number of nanoseconds to convert to ticks
|
||||
*
|
||||
* @return uint32_t The number of ticks corresponding to 'nsecs'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_nsecs_to_ticks(uint32_t nsecs)
|
||||
{
|
||||
return (nsecs * g_os_cputime.ticks_per_usec + 999) / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* os cputime ticks to nsecs
|
||||
*
|
||||
* Convert the given number of ticks into nanoseconds.
|
||||
*
|
||||
* @param ticks The number of ticks to convert to nanoseconds.
|
||||
*
|
||||
* @return uint32_t The number of nanoseconds corresponding to 'ticks'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_ticks_to_nsecs(uint32_t ticks)
|
||||
{
|
||||
return (ticks * 1000 + g_os_cputime.ticks_per_usec - 1) /
|
||||
g_os_cputime.ticks_per_usec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSCPUTime
|
||||
* @} OSKernel
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,90 @@
|
||||
#include "os/os_cputime.h"
|
||||
|
||||
/**
|
||||
* This module implements cputime functionality for timers for which:
|
||||
* a. freq is a power of 2 Hz, and
|
||||
* b. 256 Hz <= freq < 1 MHz
|
||||
*/
|
||||
|
||||
#if defined(OS_CPUTIME_FREQ_PWR2)
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel Operating System Kernel
|
||||
* @{
|
||||
* @defgroup OSCPUTime High Resolution Timers
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* os cputime usecs to ticks
|
||||
*
|
||||
* Converts the given number of microseconds into cputime ticks.
|
||||
*
|
||||
* @param usecs The number of microseconds to convert to ticks
|
||||
*
|
||||
* @return uint32_t The number of ticks corresponding to 'usecs'
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_usecs_to_ticks(uint32_t usecs)
|
||||
{
|
||||
uint64_t ticks;
|
||||
|
||||
/*
|
||||
* Faster calculation but could be off 1 full tick since we do not
|
||||
* add residual back. Adding back the residual is commented out below, but
|
||||
* shown.
|
||||
*/
|
||||
ticks = (1ULL << 32) * MYNEWT_VAL(OS_CPUTIME_FREQ) / 1000000 * usecs;
|
||||
|
||||
/* Residual for 32768 Hz. */
|
||||
//ticks += ((uint64_t)usecs * (1526122139+1)) >> 32;
|
||||
|
||||
return ticks >> 32;
|
||||
}
|
||||
|
||||
/**
|
||||
* cputime ticks to usecs
|
||||
*
|
||||
* Convert the given number of ticks into microseconds.
|
||||
*
|
||||
* @param ticks The number of ticks to convert to microseconds.
|
||||
*
|
||||
* @return uint32_t The number of microseconds corresponding to 'ticks'
|
||||
*
|
||||
* NOTE: This calculation will overflow if the value for ticks is greater
|
||||
* than 140737488. I am not going to check that here because that many ticks
|
||||
* is about 4222 seconds, way more than what this routine should be used for.
|
||||
*/
|
||||
uint32_t
|
||||
os_cputime_ticks_to_usecs(uint32_t ticks)
|
||||
{
|
||||
uint32_t usecs;
|
||||
uint32_t shift;
|
||||
uint32_t freq;
|
||||
|
||||
/* Given: `freq = 2^n`, calculate `n`. */
|
||||
/* Note: this looks like a lot of work, but gcc can optimize it away since
|
||||
* `freq` is known at compile time.
|
||||
*/
|
||||
freq = MYNEWT_VAL(OS_CPUTIME_FREQ);
|
||||
shift = 0;
|
||||
while (freq != 0) {
|
||||
freq >>= 1;
|
||||
shift++;
|
||||
}
|
||||
|
||||
if (shift <= 7) {
|
||||
return 0;
|
||||
}
|
||||
shift -= 7;
|
||||
|
||||
usecs = ((ticks >> shift) * 15625) + (((ticks & 0x1ff) * 15625) >> shift);
|
||||
return usecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSCPUTime
|
||||
* @} OSKernel
|
||||
*/
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
#include "os/queue.h"
|
||||
#include "os/os_dev.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSDevice Device Framework
|
||||
* @{
|
||||
*/
|
||||
|
||||
static STAILQ_HEAD(, os_dev) g_os_dev_list;
|
||||
|
||||
static int
|
||||
os_dev_init(struct os_dev *dev, char *name, uint8_t stage,
|
||||
uint8_t priority, os_dev_init_func_t od_init, void *arg)
|
||||
{
|
||||
dev->od_name = name;
|
||||
dev->od_stage = stage;
|
||||
dev->od_priority = priority;
|
||||
/* assume these are set after the fact. */
|
||||
dev->od_flags = 0;
|
||||
dev->od_open_ref = 0;
|
||||
dev->od_init = od_init;
|
||||
dev->od_init_arg = arg;
|
||||
memset(&dev->od_handlers, 0, sizeof(dev->od_handlers));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the device to the device tree. This is a private function.
|
||||
*
|
||||
* @param dev The device to add to the device tree.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
static int
|
||||
os_dev_add(struct os_dev *dev)
|
||||
{
|
||||
struct os_dev *cur_dev;
|
||||
|
||||
/* If no devices present, insert into head */
|
||||
if (STAILQ_FIRST(&g_os_dev_list) == NULL) {
|
||||
STAILQ_INSERT_HEAD(&g_os_dev_list, dev, od_next);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Add devices to the list, sorted first by stage, then by
|
||||
* priority. Keep sorted in this order for initialization
|
||||
* stage.
|
||||
*/
|
||||
cur_dev = NULL;
|
||||
STAILQ_FOREACH(cur_dev, &g_os_dev_list, od_next) {
|
||||
if (cur_dev->od_stage > dev->od_stage) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (dev->od_priority >= cur_dev->od_priority) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (cur_dev) {
|
||||
STAILQ_INSERT_AFTER(&g_os_dev_list, cur_dev, dev, od_next);
|
||||
} else {
|
||||
STAILQ_INSERT_TAIL(&g_os_dev_list, dev, od_next);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call device initialize routine, and mark it ready. This is a private
|
||||
* function.
|
||||
*
|
||||
* @param dev The device to initialize.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
static int
|
||||
os_dev_initialize(struct os_dev *dev)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = dev->od_init(dev, dev->od_init_arg);
|
||||
if (rc != 0) {
|
||||
if (dev->od_flags & OS_DEV_F_INIT_CRITICAL) {
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
dev->od_flags |= OS_DEV_F_STATUS_READY;
|
||||
}
|
||||
return 0;
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new device in the kernel.
|
||||
*
|
||||
* @param dev The device to create.
|
||||
* @param name The name of the device to create.
|
||||
* @param stage The stage to initialize that device to.
|
||||
* @param priority The priority of initializing that device
|
||||
* @param od_init The initialization function to call for this
|
||||
* device.
|
||||
* @param arg The argument to provide this device initialization
|
||||
* function.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
os_dev_create(struct os_dev *dev, char *name, uint8_t stage,
|
||||
uint8_t priority, os_dev_init_func_t od_init, void *arg)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_dev_init(dev, name, stage, priority, od_init, arg);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
rc = os_dev_add(dev);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (g_os_started) {
|
||||
rc = os_dev_initialize(dev);
|
||||
}
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize all devices for a given state.
|
||||
*
|
||||
* @param stage The stage to initialize.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
os_dev_initialize_all(uint8_t stage)
|
||||
{
|
||||
struct os_dev *dev;
|
||||
int rc = 0;
|
||||
|
||||
STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
|
||||
if (dev->od_stage == stage) {
|
||||
rc = os_dev_initialize(dev);
|
||||
if (rc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Suspend all devices.
|
||||
*
|
||||
* @param dev The device to suspend
|
||||
* @param suspend_t The number of ticks to suspend this device for
|
||||
* @param force Whether or not to force suspending the device
|
||||
*
|
||||
* @return 0 on success, or a non-zero error code if one of the devices
|
||||
* returned it.
|
||||
*/
|
||||
int
|
||||
os_dev_suspend_all(os_time_t suspend_t, uint8_t force)
|
||||
{
|
||||
struct os_dev *dev;
|
||||
int suspend_failure;
|
||||
int rc;
|
||||
|
||||
suspend_failure = 0;
|
||||
STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
|
||||
rc = os_dev_suspend(dev, suspend_t, force);
|
||||
if (rc != 0) {
|
||||
suspend_failure = OS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return (suspend_failure);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resume all the devices that were suspended.
|
||||
*
|
||||
* @return 0 on success, -1 if any of the devices have failed to resume.
|
||||
*/
|
||||
int
|
||||
os_dev_resume_all(void)
|
||||
{
|
||||
struct os_dev *dev;
|
||||
int rc;
|
||||
|
||||
STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
|
||||
rc = os_dev_resume(dev);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a device by name.
|
||||
*
|
||||
* WARNING: This should be called before any locking on the device is done, or
|
||||
* the device list itself is modified in any context. There is no locking.
|
||||
*
|
||||
* @param name The name of the device to look up.
|
||||
*
|
||||
* @return A pointer to the device corresponding to name, or NULL if not found.
|
||||
*/
|
||||
struct os_dev *
|
||||
os_dev_lookup(char *name)
|
||||
{
|
||||
struct os_dev *dev;
|
||||
|
||||
dev = NULL;
|
||||
STAILQ_FOREACH(dev, &g_os_dev_list, od_next) {
|
||||
if (!strcmp(dev->od_name, name)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a device.
|
||||
*
|
||||
* @param dev The device to open
|
||||
* @param timo The timeout to open the device, if not specified.
|
||||
* @param arg The argument to the device open() call.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
struct os_dev *
|
||||
os_dev_open(char *devname, uint32_t timo, void *arg)
|
||||
{
|
||||
struct os_dev *dev;
|
||||
os_sr_t sr;
|
||||
int rc;
|
||||
|
||||
dev = os_dev_lookup(devname);
|
||||
if (dev == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Device is not ready to be opened. */
|
||||
if ((dev->od_flags & OS_DEV_F_STATUS_READY) == 0) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
if (dev->od_handlers.od_open) {
|
||||
rc = dev->od_handlers.od_open(dev, timo, arg);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
++dev->od_open_ref;
|
||||
dev->od_flags |= OS_DEV_F_STATUS_OPEN;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (dev);
|
||||
err:
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close a device.
|
||||
*
|
||||
* @param dev The device to close
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
os_dev_close(struct os_dev *dev)
|
||||
{
|
||||
int rc;
|
||||
os_sr_t sr;
|
||||
|
||||
if (dev->od_handlers.od_close) {
|
||||
rc = dev->od_handlers.od_close(dev);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
if (--dev->od_open_ref == 0) {
|
||||
dev->od_flags &= ~OS_DEV_F_STATUS_OPEN;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the device list. This function does not close any devices or free
|
||||
* any resources; its purpose is to allow a full system reset between unit
|
||||
* tests.
|
||||
*/
|
||||
void
|
||||
os_dev_reset(void)
|
||||
{
|
||||
STAILQ_INIT(&g_os_dev_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSDevice
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,354 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
#include "os/os_trace_api.h"
|
||||
|
||||
#include "os/os.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSEvent Event Queues
|
||||
* @{
|
||||
*/
|
||||
|
||||
static struct os_eventq os_eventq_main;
|
||||
|
||||
/**
|
||||
* Initialize the event queue
|
||||
*
|
||||
* @param evq The event queue to initialize
|
||||
*/
|
||||
void
|
||||
os_eventq_init(struct os_eventq *evq)
|
||||
{
|
||||
memset(evq, 0, sizeof(*evq));
|
||||
STAILQ_INIT(&evq->evq_list);
|
||||
}
|
||||
|
||||
int
|
||||
os_eventq_inited(const struct os_eventq *evq)
|
||||
{
|
||||
return evq->evq_list.stqh_last != NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put an event on the event queue.
|
||||
*
|
||||
* @param evq The event queue to put an event on
|
||||
* @param ev The event to put on the queue
|
||||
*/
|
||||
void
|
||||
os_eventq_put(struct os_eventq *evq, struct os_event *ev)
|
||||
{
|
||||
int resched;
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/* Do not queue if already queued */
|
||||
if (OS_EVENT_QUEUED(ev)) {
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return;
|
||||
}
|
||||
|
||||
os_trace_void(OS_TRACE_ID_EVQ_PUT);
|
||||
|
||||
/* Queue the event */
|
||||
ev->ev_queued = 1;
|
||||
STAILQ_INSERT_TAIL(&evq->evq_list, ev, ev_next);
|
||||
|
||||
resched = 0;
|
||||
if (evq->evq_task) {
|
||||
/* If task waiting on event, wake it up.
|
||||
* Check if task is sleeping, because another event
|
||||
* queue may have woken this task up beforehand.
|
||||
*/
|
||||
if (evq->evq_task->t_state == OS_TASK_SLEEP) {
|
||||
os_sched_wakeup(evq->evq_task);
|
||||
resched = 1;
|
||||
}
|
||||
/* Either way, NULL out the task, because the task will
|
||||
* be awake upon exit of this function.
|
||||
*/
|
||||
evq->evq_task = NULL;
|
||||
}
|
||||
|
||||
os_trace_end_call(OS_TRACE_ID_EVQ_PUT);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
if (resched) {
|
||||
os_sched(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
struct os_event *
|
||||
os_eventq_get_no_wait(struct os_eventq *evq)
|
||||
{
|
||||
struct os_event *ev;
|
||||
|
||||
ev = STAILQ_FIRST(&evq->evq_list);
|
||||
if (ev) {
|
||||
STAILQ_REMOVE(&evq->evq_list, ev, os_event, ev_next);
|
||||
ev->ev_queued = 0;
|
||||
}
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull a single item from an event queue. This function blocks until there
|
||||
* is an item on the event queue to read.
|
||||
*
|
||||
* @param evq The event queue to pull an event from
|
||||
*
|
||||
* @return The event from the queue
|
||||
*/
|
||||
struct os_event *
|
||||
os_eventq_get(struct os_eventq *evq)
|
||||
{
|
||||
struct os_event *ev;
|
||||
os_sr_t sr;
|
||||
struct os_task *t;
|
||||
|
||||
t = os_sched_get_current_task();
|
||||
if (evq->evq_owner != t) {
|
||||
if (evq->evq_owner == NULL) {
|
||||
evq->evq_owner = t;
|
||||
} else {
|
||||
/*
|
||||
* A task is trying to read from event queue which is handled
|
||||
* by another.
|
||||
*/
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
os_trace_void(OS_TRACE_ID_EVQ_GET);
|
||||
pull_one:
|
||||
ev = STAILQ_FIRST(&evq->evq_list);
|
||||
if (ev) {
|
||||
STAILQ_REMOVE(&evq->evq_list, ev, os_event, ev_next);
|
||||
ev->ev_queued = 0;
|
||||
t->t_flags &= ~OS_TASK_FLAG_EVQ_WAIT;
|
||||
} else {
|
||||
evq->evq_task = t;
|
||||
os_sched_sleep(evq->evq_task, OS_TIMEOUT_NEVER);
|
||||
t->t_flags |= OS_TASK_FLAG_EVQ_WAIT;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
os_sched(NULL);
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
evq->evq_task = NULL;
|
||||
goto pull_one;
|
||||
}
|
||||
os_trace_end_call(OS_TRACE_ID_EVQ_GET);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (ev);
|
||||
}
|
||||
|
||||
void
|
||||
os_eventq_run(struct os_eventq *evq)
|
||||
{
|
||||
struct os_event *ev;
|
||||
|
||||
ev = os_eventq_get(evq);
|
||||
assert(ev->ev_cb != NULL);
|
||||
|
||||
ev->ev_cb(ev);
|
||||
}
|
||||
|
||||
static struct os_event *
|
||||
os_eventq_poll_0timo(struct os_eventq **evq, int nevqs)
|
||||
{
|
||||
struct os_event *ev;
|
||||
os_sr_t sr;
|
||||
int i;
|
||||
|
||||
ev = NULL;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
for (i = 0; i < nevqs; i++) {
|
||||
ev = STAILQ_FIRST(&evq[i]->evq_list);
|
||||
if (ev) {
|
||||
STAILQ_REMOVE(&evq[i]->evq_list, ev, os_event, ev_next);
|
||||
ev->ev_queued = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Poll the list of event queues specified by the evq parameter
|
||||
* (size nevqs), and return the "first" event available on any of
|
||||
* the queues. Event queues are searched in the order that they
|
||||
* are passed in the array.
|
||||
*
|
||||
* @param evq Array of event queues
|
||||
* @param nevqs Number of event queues in evq
|
||||
* @param timo Timeout, forever if OS_WAIT_FOREVER is passed to poll.
|
||||
*
|
||||
* @return An event, or NULL if no events available
|
||||
*/
|
||||
struct os_event *
|
||||
os_eventq_poll(struct os_eventq **evq, int nevqs, os_time_t timo)
|
||||
{
|
||||
struct os_event *ev;
|
||||
struct os_task *cur_t;
|
||||
int i, j;
|
||||
os_sr_t sr;
|
||||
|
||||
/* If the timeout is 0, don't involve the scheduler at all. Grab an event
|
||||
* if one is available, else return immediately.
|
||||
*/
|
||||
if (timo == 0) {
|
||||
return os_eventq_poll_0timo(evq, nevqs);
|
||||
}
|
||||
|
||||
ev = NULL;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
cur_t = os_sched_get_current_task();
|
||||
|
||||
for (i = 0; i < nevqs; i++) {
|
||||
ev = STAILQ_FIRST(&evq[i]->evq_list);
|
||||
if (ev) {
|
||||
STAILQ_REMOVE(&evq[i]->evq_list, ev, os_event, ev_next);
|
||||
ev->ev_queued = 0;
|
||||
/* Reset the items that already have an evq task set. */
|
||||
for (j = 0; j < i; j++) {
|
||||
evq[j]->evq_task = NULL;
|
||||
}
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
goto has_event;
|
||||
}
|
||||
evq[i]->evq_task = cur_t;
|
||||
}
|
||||
|
||||
cur_t->t_flags |= OS_TASK_FLAG_EVQ_WAIT;
|
||||
|
||||
os_sched_sleep(cur_t, timo);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
os_sched(NULL);
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
cur_t->t_flags &= ~OS_TASK_FLAG_EVQ_WAIT;
|
||||
for (i = 0; i < nevqs; i++) {
|
||||
/* Go through the entire loop to clear the evq_task variable,
|
||||
* given this task is no longer sleeping on the event queues.
|
||||
* Return the first event found, so only grab the event if
|
||||
* we haven't found one.
|
||||
*/
|
||||
if (!ev) {
|
||||
ev = STAILQ_FIRST(&evq[i]->evq_list);
|
||||
if (ev) {
|
||||
STAILQ_REMOVE(&evq[i]->evq_list, ev, os_event, ev_next);
|
||||
ev->ev_queued = 0;
|
||||
}
|
||||
}
|
||||
evq[i]->evq_task = NULL;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
has_event:
|
||||
return (ev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an event from the queue.
|
||||
*
|
||||
* @param evq The event queue to remove the event from
|
||||
* @param ev The event to remove from the queue
|
||||
*/
|
||||
void
|
||||
os_eventq_remove(struct os_eventq *evq, struct os_event *ev)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
if (OS_EVENT_QUEUED(ev)) {
|
||||
STAILQ_REMOVE(&evq->evq_list, ev, os_event, ev_next);
|
||||
}
|
||||
ev->ev_queued = 0;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the default event queue processed by OS main task.
|
||||
*
|
||||
* @return The default event queue.
|
||||
*/
|
||||
struct os_eventq *
|
||||
os_eventq_dflt_get(void)
|
||||
{
|
||||
return &os_eventq_main;
|
||||
}
|
||||
|
||||
/**
|
||||
* [DEPRECATED - packages should manually enqueue start events to the default
|
||||
* task instead of calling this function]
|
||||
*
|
||||
* Reassigns an event queue pointer to the specified value. This function is
|
||||
* used for configuring a package to use a particular event queue. A package's
|
||||
* event queue can generally be reassigned repeatedly. If the package has a
|
||||
* startup event, the event is moved from the current queue (if any) to the
|
||||
* specified queue.
|
||||
*
|
||||
* @param cur_evq Points to the eventq pointer to reassign.
|
||||
* *cur_evq should be NULL if the package's
|
||||
* eventq has not been assigned yet.
|
||||
* @param new_evq The eventq that the package should be
|
||||
* associated with.
|
||||
* @param start_ev The package's startup event, if any. If this
|
||||
* is non-NULL, the event gets removed from
|
||||
* the current queue (if set), and enqueued to
|
||||
* the new eventq.
|
||||
*/
|
||||
void
|
||||
os_eventq_designate(struct os_eventq **cur_evq,
|
||||
struct os_eventq *new_evq,
|
||||
struct os_event *start_ev)
|
||||
{
|
||||
struct os_eventq *prev_evq;
|
||||
|
||||
prev_evq = *cur_evq;
|
||||
*cur_evq = new_evq;
|
||||
|
||||
if (start_ev != NULL) {
|
||||
if (start_ev->ev_queued) {
|
||||
assert(prev_evq != NULL);
|
||||
os_eventq_remove(prev_evq, start_ev);
|
||||
}
|
||||
os_eventq_put(new_evq, start_ev);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSEvent
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* 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 "syscfg/syscfg.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include "os/os_mutex.h"
|
||||
#include "os/os_heap.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSGeneral
|
||||
* @{
|
||||
*/
|
||||
|
||||
#if MYNEWT_VAL(OS_SCHEDULING)
|
||||
static struct os_mutex os_malloc_mutex;
|
||||
#endif
|
||||
|
||||
static void
|
||||
os_malloc_lock(void)
|
||||
{
|
||||
#if MYNEWT_VAL(OS_SCHEDULING)
|
||||
int rc;
|
||||
|
||||
if (g_os_started) {
|
||||
rc = os_mutex_pend(&os_malloc_mutex, 0xffffffff);
|
||||
assert(rc == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
os_malloc_unlock(void)
|
||||
{
|
||||
#if MYNEWT_VAL(OS_SCHEDULING)
|
||||
int rc;
|
||||
|
||||
if (g_os_started) {
|
||||
rc = os_mutex_release(&os_malloc_mutex);
|
||||
assert(rc == 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Operating system level malloc(). This ensures that a safe malloc occurs
|
||||
* within the context of the OS. Depending on platform, the OS may rely on
|
||||
* libc's malloc() implementation, which is not guaranteed to be thread-safe.
|
||||
* This malloc() will always be thread-safe.
|
||||
*
|
||||
* @param size The number of bytes to allocate
|
||||
*
|
||||
* @return A pointer to the memory region allocated.
|
||||
*/
|
||||
void *
|
||||
os_malloc(size_t size)
|
||||
{
|
||||
void *ptr;
|
||||
|
||||
os_malloc_lock();
|
||||
ptr = malloc(size);
|
||||
os_malloc_unlock();
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Operating system level free(). See description of os_malloc() for reasoning.
|
||||
*
|
||||
* Free's memory allocated by malloc.
|
||||
*
|
||||
* @param mem The memory to free.
|
||||
*/
|
||||
void
|
||||
os_free(void *mem)
|
||||
{
|
||||
os_malloc_lock();
|
||||
free(mem);
|
||||
os_malloc_unlock();
|
||||
}
|
||||
|
||||
/**
|
||||
* Operating system level realloc(). See description of os_malloc() for reasoning.
|
||||
*
|
||||
* Reallocates the memory at ptr, to be size contiguouos bytes.
|
||||
*
|
||||
* @param ptr A pointer to the memory to allocate
|
||||
* @param size The number of contiguouos bytes to allocate at that location
|
||||
*
|
||||
* @return A pointer to memory of size, or NULL on failure to allocate
|
||||
*/
|
||||
void *
|
||||
os_realloc(void *ptr, size_t size)
|
||||
{
|
||||
void *new_ptr;
|
||||
|
||||
os_malloc_lock();
|
||||
new_ptr = realloc(ptr, size);
|
||||
os_malloc_unlock();
|
||||
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSGeneral
|
||||
* @} OS Kernel
|
||||
*/
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSMempool Memory Pools
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define OS_MEM_TRUE_BLOCK_SIZE(bsize) OS_ALIGN(bsize, OS_ALIGNMENT)
|
||||
#define OS_MEMPOOL_TRUE_BLOCK_SIZE(mp) OS_MEM_TRUE_BLOCK_SIZE(mp->mp_block_size)
|
||||
|
||||
STAILQ_HEAD(, os_mempool) g_os_mempool_list =
|
||||
STAILQ_HEAD_INITIALIZER(g_os_mempool_list);
|
||||
|
||||
#if MYNEWT_VAL(OS_MEMPOOL_POISON)
|
||||
static uint32_t os_mem_poison = 0xde7ec7ed;
|
||||
|
||||
static void
|
||||
os_mempool_poison(void *start, int sz)
|
||||
{
|
||||
int i;
|
||||
char *p = start;
|
||||
|
||||
for (i = sizeof(struct os_memblock); i < sz;
|
||||
i = i + sizeof(os_mem_poison)) {
|
||||
memcpy(p + i, &os_mem_poison, min(sizeof(os_mem_poison), sz - i));
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
os_mempool_poison_check(void *start, int sz)
|
||||
{
|
||||
int i;
|
||||
char *p = start;
|
||||
|
||||
for (i = sizeof(struct os_memblock); i < sz;
|
||||
i = i + sizeof(os_mem_poison)) {
|
||||
assert(!memcmp(p + i, &os_mem_poison,
|
||||
min(sizeof(os_mem_poison), sz - i)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
#define os_mempool_poison(start, sz)
|
||||
#define os_mempool_poison_check(start, sz)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* os mempool init
|
||||
*
|
||||
* Initialize a memory pool.
|
||||
*
|
||||
* @param mp Pointer to a pointer to a mempool
|
||||
* @param blocks The number of blocks in the pool
|
||||
* @param blocks_size The size of the block, in bytes.
|
||||
* @param membuf Pointer to memory to contain blocks.
|
||||
* @param name Name of the pool.
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t
|
||||
os_mempool_init(struct os_mempool *mp, int blocks, int block_size,
|
||||
void *membuf, char *name)
|
||||
{
|
||||
int true_block_size;
|
||||
uint8_t *block_addr;
|
||||
struct os_memblock *block_ptr;
|
||||
|
||||
/* Check for valid parameters */
|
||||
if (!mp || (blocks < 0) || (block_size <= sizeof(struct os_memblock))) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
if ((!membuf) && (blocks != 0)) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
if (membuf != NULL) {
|
||||
/* Blocks need to be sized properly and memory buffer should be
|
||||
* aligned
|
||||
*/
|
||||
if (((uint32_t)membuf & (OS_ALIGNMENT - 1)) != 0) {
|
||||
return OS_MEM_NOT_ALIGNED;
|
||||
}
|
||||
}
|
||||
true_block_size = OS_MEM_TRUE_BLOCK_SIZE(block_size);
|
||||
|
||||
/* Initialize the memory pool structure */
|
||||
mp->mp_block_size = block_size;
|
||||
mp->mp_num_free = blocks;
|
||||
mp->mp_min_free = blocks;
|
||||
mp->mp_num_blocks = blocks;
|
||||
mp->mp_membuf_addr = (uint32_t)membuf;
|
||||
mp->name = name;
|
||||
os_mempool_poison(membuf, true_block_size);
|
||||
SLIST_FIRST(mp) = membuf;
|
||||
|
||||
/* Chain the memory blocks to the free list */
|
||||
block_addr = (uint8_t *)membuf;
|
||||
block_ptr = (struct os_memblock *)block_addr;
|
||||
while (blocks > 1) {
|
||||
block_addr += true_block_size;
|
||||
os_mempool_poison(block_addr, true_block_size);
|
||||
SLIST_NEXT(block_ptr, mb_next) = (struct os_memblock *)block_addr;
|
||||
block_ptr = (struct os_memblock *)block_addr;
|
||||
--blocks;
|
||||
}
|
||||
|
||||
/* Last one in the list should be NULL */
|
||||
SLIST_NEXT(block_ptr, mb_next) = NULL;
|
||||
|
||||
STAILQ_INSERT_TAIL(&g_os_mempool_list, mp, mp_list);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an integrity check of the specified mempool. This function
|
||||
* attempts to detect memory corruption in the specified memory pool.
|
||||
*
|
||||
* @param mp The mempool to check.
|
||||
*
|
||||
* @return true if the memory pool passes the integrity
|
||||
* check;
|
||||
* false if the memory pool is corrupt.
|
||||
*/
|
||||
bool
|
||||
os_mempool_is_sane(const struct os_mempool *mp)
|
||||
{
|
||||
struct os_memblock *block;
|
||||
|
||||
/* Verify that each block in the free list belongs to the mempool. */
|
||||
SLIST_FOREACH(block, mp, mb_next) {
|
||||
if (!os_memblock_from(mp, block)) {
|
||||
return false;
|
||||
}
|
||||
os_mempool_poison_check(block, OS_MEMPOOL_TRUE_BLOCK_SIZE(mp));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a memory block was allocated from the specified mempool.
|
||||
*
|
||||
* @param mp The mempool to check as parent.
|
||||
* @param block_addr The memory block to check as child.
|
||||
*
|
||||
* @return 0 if the block does not belong to the mempool;
|
||||
* 1 if the block does belong to the mempool.
|
||||
*/
|
||||
int
|
||||
os_memblock_from(const struct os_mempool *mp, const void *block_addr)
|
||||
{
|
||||
uint32_t true_block_size;
|
||||
uint32_t baddr32;
|
||||
uint32_t end;
|
||||
|
||||
_Static_assert(sizeof block_addr == sizeof baddr32,
|
||||
"Pointer to void must be 32-bits.");
|
||||
|
||||
baddr32 = (uint32_t)block_addr;
|
||||
true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
|
||||
end = mp->mp_membuf_addr + (mp->mp_num_blocks * true_block_size);
|
||||
|
||||
/* Check that the block is in the memory buffer range. */
|
||||
if ((baddr32 < mp->mp_membuf_addr) || (baddr32 >= end)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* All freed blocks should be on true block size boundaries! */
|
||||
if (((baddr32 - mp->mp_membuf_addr) % true_block_size) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* os memblock get
|
||||
*
|
||||
* Get a memory block from a memory pool
|
||||
*
|
||||
* @param mp Pointer to the memory pool
|
||||
*
|
||||
* @return void* Pointer to block if available; NULL otherwise
|
||||
*/
|
||||
void *
|
||||
os_memblock_get(struct os_mempool *mp)
|
||||
{
|
||||
os_sr_t sr;
|
||||
struct os_memblock *block;
|
||||
|
||||
/* Check to make sure they passed in a memory pool (or something) */
|
||||
block = NULL;
|
||||
if (mp) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
/* Check for any free */
|
||||
if (mp->mp_num_free) {
|
||||
/* Get a free block */
|
||||
block = SLIST_FIRST(mp);
|
||||
|
||||
os_mempool_poison_check(block, OS_MEMPOOL_TRUE_BLOCK_SIZE(mp));
|
||||
|
||||
/* Set new free list head */
|
||||
SLIST_FIRST(mp) = SLIST_NEXT(block, mb_next);
|
||||
|
||||
/* Decrement number free by 1 */
|
||||
mp->mp_num_free--;
|
||||
if (mp->mp_min_free > mp->mp_num_free) {
|
||||
mp->mp_min_free = mp->mp_num_free;
|
||||
}
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
return (void *)block;
|
||||
}
|
||||
|
||||
/**
|
||||
* os memblock put
|
||||
*
|
||||
* Puts the memory block back into the pool
|
||||
*
|
||||
* @param mp Pointer to memory pool
|
||||
* @param block_addr Pointer to memory block
|
||||
*
|
||||
* @return os_error_t
|
||||
*/
|
||||
os_error_t
|
||||
os_memblock_put(struct os_mempool *mp, void *block_addr)
|
||||
{
|
||||
os_sr_t sr;
|
||||
struct os_memblock *block;
|
||||
|
||||
/* Make sure parameters are valid */
|
||||
if ((mp == NULL) || (block_addr == NULL)) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(OS_MEMPOOL_CHECK)
|
||||
/* Check that the block we are freeing is a valid block! */
|
||||
assert(os_memblock_from(mp, block_addr));
|
||||
|
||||
/*
|
||||
* Check for duplicate free.
|
||||
*/
|
||||
SLIST_FOREACH(block, mp, mb_next) {
|
||||
assert(block != (struct os_memblock *)block_addr);
|
||||
}
|
||||
#endif
|
||||
os_mempool_poison(block_addr, OS_MEMPOOL_TRUE_BLOCK_SIZE(mp));
|
||||
block = (struct os_memblock *)block_addr;
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/* Chain current free list pointer to this block; make this block head */
|
||||
SLIST_NEXT(block, mb_next) = SLIST_FIRST(mp);
|
||||
SLIST_FIRST(mp) = block;
|
||||
|
||||
/* XXX: Should we check that the number free <= number blocks? */
|
||||
/* Increment number free */
|
||||
mp->mp_num_free++;
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
|
||||
struct os_mempool *
|
||||
os_mempool_info_get_next(struct os_mempool *mp, struct os_mempool_info *omi)
|
||||
{
|
||||
struct os_mempool *cur;
|
||||
|
||||
if (mp == NULL) {
|
||||
cur = STAILQ_FIRST(&g_os_mempool_list);
|
||||
} else {
|
||||
cur = STAILQ_NEXT(mp, mp_list);
|
||||
}
|
||||
|
||||
if (cur == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
omi->omi_block_size = cur->mp_block_size;
|
||||
omi->omi_num_blocks = cur->mp_num_blocks;
|
||||
omi->omi_num_free = cur->mp_num_free;
|
||||
omi->omi_min_free = cur->mp_min_free;
|
||||
strncpy(omi->omi_name, cur->name, sizeof(omi->omi_name));
|
||||
|
||||
return (cur);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @} OSMempool
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
|
||||
#include "../os/os_priv.h"
|
||||
#include "sysinit/sysinit.h"
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "os/os_mempool.h"
|
||||
#include "mem/mem.h"
|
||||
|
||||
#if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
|
||||
#define SYSINIT_MSYS_1_MEMBLOCK_SIZE \
|
||||
OS_ALIGN(MYNEWT_VAL(MSYS_1_BLOCK_SIZE), 4)
|
||||
#define SYSINIT_MSYS_1_MEMPOOL_SIZE \
|
||||
OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_1_BLOCK_COUNT), \
|
||||
SYSINIT_MSYS_1_MEMBLOCK_SIZE)
|
||||
static os_membuf_t os_msys_init_1_data[SYSINIT_MSYS_1_MEMPOOL_SIZE];
|
||||
static struct os_mbuf_pool os_msys_init_1_mbuf_pool;
|
||||
static struct os_mempool os_msys_init_1_mempool;
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
|
||||
#define SYSINIT_MSYS_2_MEMBLOCK_SIZE \
|
||||
OS_ALIGN(MYNEWT_VAL(MSYS_2_BLOCK_SIZE), 4)
|
||||
#define SYSINIT_MSYS_2_MEMPOOL_SIZE \
|
||||
OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_2_BLOCK_COUNT), \
|
||||
SYSINIT_MSYS_2_MEMBLOCK_SIZE)
|
||||
static os_membuf_t os_msys_init_2_data[SYSINIT_MSYS_2_MEMPOOL_SIZE];
|
||||
static struct os_mbuf_pool os_msys_init_2_mbuf_pool;
|
||||
static struct os_mempool os_msys_init_2_mempool;
|
||||
#endif
|
||||
|
||||
static void
|
||||
os_msys_init_once(void *data, struct os_mempool *mempool,
|
||||
struct os_mbuf_pool *mbuf_pool,
|
||||
int block_count, int block_size, char *name)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = mem_init_mbuf_pool(data, mempool, mbuf_pool, block_count, block_size,
|
||||
name);
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
|
||||
rc = os_msys_register(mbuf_pool);
|
||||
SYSINIT_PANIC_ASSERT(rc == 0);
|
||||
}
|
||||
|
||||
void
|
||||
os_msys_init(void)
|
||||
{
|
||||
os_msys_reset();
|
||||
|
||||
(void)os_msys_init_once;
|
||||
#if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
|
||||
os_msys_init_once(os_msys_init_1_data,
|
||||
&os_msys_init_1_mempool,
|
||||
&os_msys_init_1_mbuf_pool,
|
||||
MYNEWT_VAL(MSYS_1_BLOCK_COUNT),
|
||||
SYSINIT_MSYS_1_MEMBLOCK_SIZE,
|
||||
"msys_1");
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
|
||||
os_msys_init_once(os_msys_init_2_data,
|
||||
&os_msys_init_2_mempool,
|
||||
&os_msys_init_2_mbuf_pool,
|
||||
MYNEWT_VAL(MSYS_2_BLOCK_COUNT),
|
||||
SYSINIT_MSYS_2_MEMBLOCK_SIZE,
|
||||
"msys_2");
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
#include "os/os_trace_api.h"
|
||||
#include <assert.h>
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSMutex Mutexes
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* os mutex create
|
||||
*
|
||||
* Create a mutex and initialize it.
|
||||
*
|
||||
* @param mu Pointer to mutex
|
||||
*
|
||||
* @return os_error_t
|
||||
* OS_INVALID_PARM Mutex passed in was NULL.
|
||||
* OS_OK no error.
|
||||
*/
|
||||
os_error_t
|
||||
os_mutex_init(struct os_mutex *mu)
|
||||
{
|
||||
if (!mu) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
os_trace_void(OS_TRACE_ID_MUTEX_INIT);
|
||||
/* Initialize to 0 */
|
||||
mu->mu_prio = 0;
|
||||
mu->mu_level = 0;
|
||||
mu->mu_owner = NULL;
|
||||
SLIST_FIRST(&mu->mu_head) = NULL;
|
||||
os_trace_end_call(OS_TRACE_ID_MUTEX_INIT);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* os mutex release
|
||||
*
|
||||
* Release a mutex.
|
||||
*
|
||||
* @param mu Pointer to the mutex to be released
|
||||
*
|
||||
* @return os_error_t
|
||||
* OS_INVALID_PARM Mutex passed in was NULL.
|
||||
* OS_BAD_MUTEX Mutex was not granted to current task (not owner).
|
||||
* OS_OK No error
|
||||
*/
|
||||
os_error_t
|
||||
os_mutex_release(struct os_mutex *mu)
|
||||
{
|
||||
int resched;
|
||||
os_sr_t sr;
|
||||
struct os_task *current;
|
||||
struct os_task *rdy;
|
||||
|
||||
/* Check if OS is started */
|
||||
if (!g_os_started) {
|
||||
return (OS_NOT_STARTED);
|
||||
}
|
||||
|
||||
/* Check for valid mutex */
|
||||
if (!mu) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
/* We better own this mutex! */
|
||||
current = os_sched_get_current_task();
|
||||
if ((mu->mu_level == 0) || (mu->mu_owner != current)) {
|
||||
return (OS_BAD_MUTEX);
|
||||
}
|
||||
|
||||
/* Decrement nesting level by 1. If not zero, nested (so dont release!) */
|
||||
--mu->mu_level;
|
||||
if (mu->mu_level != 0) {
|
||||
return (OS_OK);
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
os_trace_void(OS_TRACE_ID_MUTEX_RELEASE);
|
||||
|
||||
/* Restore owner task's priority; resort list if different */
|
||||
if (current->t_prio != mu->mu_prio) {
|
||||
current->t_prio = mu->mu_prio;
|
||||
os_sched_resort(current);
|
||||
}
|
||||
|
||||
/* Check if tasks are waiting for the mutex */
|
||||
rdy = SLIST_FIRST(&mu->mu_head);
|
||||
if (rdy) {
|
||||
/* There is one waiting. Wake it up */
|
||||
assert(rdy->t_obj);
|
||||
os_sched_wakeup(rdy);
|
||||
|
||||
/* Set mutex internals */
|
||||
mu->mu_level = 1;
|
||||
mu->mu_prio = rdy->t_prio;
|
||||
}
|
||||
|
||||
/* Set new owner of mutex (or NULL if not owned) */
|
||||
mu->mu_owner = rdy;
|
||||
if (rdy) {
|
||||
rdy->t_lockcnt++;
|
||||
}
|
||||
--current->t_lockcnt;
|
||||
|
||||
/* Do we need to re-schedule? */
|
||||
resched = 0;
|
||||
rdy = os_sched_next_task();
|
||||
if (rdy != current) {
|
||||
resched = 1;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
/* Re-schedule if needed */
|
||||
if (resched) {
|
||||
os_sched(rdy);
|
||||
}
|
||||
os_trace_end_call(OS_TRACE_ID_MUTEX_RELEASE);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* os mutex pend
|
||||
*
|
||||
* Pend (wait) for a mutex.
|
||||
*
|
||||
* @param mu Pointer to mutex.
|
||||
* @param timeout Timeout, in os ticks. A timeout of 0 means do
|
||||
* not wait if not available. A timeout of
|
||||
* 0xFFFFFFFF means wait forever.
|
||||
*
|
||||
*
|
||||
* @return os_error_t
|
||||
* OS_INVALID_PARM Mutex passed in was NULL.
|
||||
* OS_TIMEOUT Mutex was owned by another task and timeout=0
|
||||
* OS_OK no error.
|
||||
*/
|
||||
os_error_t
|
||||
os_mutex_pend(struct os_mutex *mu, uint32_t timeout)
|
||||
{
|
||||
os_sr_t sr;
|
||||
os_error_t rc;
|
||||
struct os_task *current;
|
||||
struct os_task *entry;
|
||||
struct os_task *last;
|
||||
|
||||
/* OS must be started when calling this function */
|
||||
if (!g_os_started) {
|
||||
return (OS_NOT_STARTED);
|
||||
}
|
||||
|
||||
/* Check for valid mutex */
|
||||
if (!mu) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/* Is this owned? */
|
||||
current = os_sched_get_current_task();
|
||||
if (mu->mu_level == 0) {
|
||||
mu->mu_owner = current;
|
||||
mu->mu_prio = current->t_prio;
|
||||
current->t_lockcnt++;
|
||||
mu->mu_level = 1;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/* Are we owner? */
|
||||
if (mu->mu_owner == current) {
|
||||
++mu->mu_level;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/* Mutex is not owned by us. If timeout is 0, return immediately */
|
||||
if (timeout == 0) {
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return OS_TIMEOUT;
|
||||
}
|
||||
|
||||
os_trace_void(OS_TRACE_ID_MUTEX_PEND);
|
||||
|
||||
/* Change priority of owner if needed */
|
||||
if (mu->mu_owner->t_prio > current->t_prio) {
|
||||
mu->mu_owner->t_prio = current->t_prio;
|
||||
os_sched_resort(mu->mu_owner);
|
||||
}
|
||||
|
||||
/* Link current task to tasks waiting for mutex */
|
||||
last = NULL;
|
||||
if (!SLIST_EMPTY(&mu->mu_head)) {
|
||||
/* Insert in priority order */
|
||||
SLIST_FOREACH(entry, &mu->mu_head, t_obj_list) {
|
||||
if (current->t_prio < entry->t_prio) {
|
||||
break;
|
||||
}
|
||||
last = entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (last) {
|
||||
SLIST_INSERT_AFTER(last, current, t_obj_list);
|
||||
} else {
|
||||
SLIST_INSERT_HEAD(&mu->mu_head, current, t_obj_list);
|
||||
}
|
||||
|
||||
/* Set mutex pointer in task */
|
||||
current->t_obj = mu;
|
||||
current->t_flags |= OS_TASK_FLAG_MUTEX_WAIT;
|
||||
os_sched_sleep(current, timeout);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
os_sched(NULL);
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
current->t_flags &= ~OS_TASK_FLAG_MUTEX_WAIT;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
/* If we are owner we did not time out. */
|
||||
if (mu->mu_owner == current) {
|
||||
rc = OS_OK;
|
||||
} else {
|
||||
rc = OS_TIMEOUT;
|
||||
}
|
||||
os_trace_end_call(OS_TRACE_ID_MUTEX_PEND);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @} OSMutex
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_OS_PRIV_
|
||||
#define H_OS_PRIV_
|
||||
|
||||
#include "os/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern struct os_task g_idle_task;
|
||||
extern struct os_task_list g_os_run_list;
|
||||
extern struct os_task_list g_os_sleep_list;
|
||||
extern struct os_task_stailq g_os_task_list;
|
||||
extern struct os_callout_list g_callout_list;
|
||||
|
||||
void os_msys_init(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "os/os.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSSanity Sanity
|
||||
* @{
|
||||
*/
|
||||
|
||||
SLIST_HEAD(, os_sanity_check) g_os_sanity_check_list =
|
||||
SLIST_HEAD_INITIALIZER(os_sanity_check_list);
|
||||
|
||||
struct os_mutex g_os_sanity_check_mu;
|
||||
|
||||
/**
|
||||
* Initialize a sanity check
|
||||
*
|
||||
* @param sc The sanity check to initialize
|
||||
*
|
||||
* @return 0 on success, error code on failure.
|
||||
*/
|
||||
int
|
||||
os_sanity_check_init(struct os_sanity_check *sc)
|
||||
{
|
||||
memset(sc, 0, sizeof(*sc));
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Lock the sanity check list
|
||||
*
|
||||
* @return 0 on success, error code on failure.
|
||||
*/
|
||||
static int
|
||||
os_sanity_check_list_lock(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!g_os_started) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
rc = os_mutex_pend(&g_os_sanity_check_mu, OS_WAIT_FOREVER);
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unlock the sanity check list
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
static int
|
||||
os_sanity_check_list_unlock(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (!g_os_started) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
rc = os_mutex_release(&g_os_sanity_check_mu);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a "task checkin" for the sanity task.
|
||||
*
|
||||
* @param t The task to check in
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int
|
||||
os_sanity_task_checkin(struct os_task *t)
|
||||
{
|
||||
int rc;
|
||||
|
||||
if (t == NULL) {
|
||||
t = os_sched_get_current_task();
|
||||
}
|
||||
|
||||
rc = os_sanity_check_reset(&t->t_sanity_check);
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Register a sanity check
|
||||
*
|
||||
* @param sc The sanity check to register
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int
|
||||
os_sanity_check_register(struct os_sanity_check *sc)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_sanity_check_list_lock();
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
SLIST_INSERT_HEAD(&g_os_sanity_check_list, sc, sc_next);
|
||||
|
||||
rc = os_sanity_check_list_unlock();
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset the os sanity check, so that it doesn't trip up the
|
||||
* sanity timer.
|
||||
*
|
||||
* @param sc The sanity check to reset
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int
|
||||
os_sanity_check_reset(struct os_sanity_check *sc)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_sanity_check_list_lock();
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
sc->sc_checkin_last = os_time_get();
|
||||
|
||||
rc = os_sanity_check_list_unlock();
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called from the IDLE task context, every MYNEWT_VAL(SANITY_INTERVAL) msecs.
|
||||
*
|
||||
* Goes through the sanity check list, and performs sanity checks. If any of
|
||||
* these checks failed, or tasks have not checked in, it resets the processor.
|
||||
*/
|
||||
void
|
||||
os_sanity_run(void)
|
||||
{
|
||||
struct os_sanity_check *sc;
|
||||
int rc;
|
||||
|
||||
rc = os_sanity_check_list_lock();
|
||||
if (rc != 0) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
SLIST_FOREACH(sc, &g_os_sanity_check_list, sc_next) {
|
||||
rc = OS_OK;
|
||||
|
||||
if (sc->sc_func) {
|
||||
rc = sc->sc_func(sc, sc->sc_arg);
|
||||
if (rc == OS_OK) {
|
||||
sc->sc_checkin_last = os_time_get();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (OS_TIME_TICK_GT(os_time_get(),
|
||||
sc->sc_checkin_last + sc->sc_checkin_itvl)) {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
rc = os_sanity_check_list_unlock();
|
||||
if (rc != 0) {
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the sanity task and mutex.
|
||||
*
|
||||
* @return 0 on success, error code on failure
|
||||
*/
|
||||
int
|
||||
os_sanity_init(void)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = os_mutex_init(&g_os_sanity_check_mu);
|
||||
if (rc != 0) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSSanity
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,377 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
#include "os/os_trace_api.h"
|
||||
#include "os/queue.h"
|
||||
#include <assert.h>
|
||||
#include "../os/os_priv.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSSched Scheduler
|
||||
* @{
|
||||
*/
|
||||
|
||||
struct os_task_list g_os_run_list = TAILQ_HEAD_INITIALIZER(g_os_run_list);
|
||||
struct os_task_list g_os_sleep_list = TAILQ_HEAD_INITIALIZER(g_os_sleep_list);
|
||||
|
||||
struct os_task *g_current_task;
|
||||
|
||||
extern os_time_t g_os_time;
|
||||
os_time_t g_os_last_ctx_sw_time;
|
||||
|
||||
/**
|
||||
* os sched insert
|
||||
*
|
||||
* Insert a task into the scheduler list. This causes the task to be evaluated
|
||||
* for running when os_sched is called.
|
||||
*
|
||||
* @param t Pointer to task to insert in run list
|
||||
*
|
||||
* @return int OS_OK: task was inserted into run list
|
||||
* OS_EINVAL: Task was not in ready state.
|
||||
*/
|
||||
os_error_t
|
||||
os_sched_insert(struct os_task *t)
|
||||
{
|
||||
struct os_task *entry;
|
||||
os_sr_t sr;
|
||||
os_error_t rc;
|
||||
|
||||
if (t->t_state != OS_TASK_READY) {
|
||||
rc = OS_EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
entry = NULL;
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
TAILQ_FOREACH(entry, &g_os_run_list, t_os_list) {
|
||||
if (t->t_prio < entry->t_prio) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry) {
|
||||
TAILQ_INSERT_BEFORE(entry, (struct os_task *) t, t_os_list);
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&g_os_run_list, (struct os_task *) t, t_os_list);
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
void
|
||||
os_sched_ctx_sw_hook(struct os_task *next_t)
|
||||
{
|
||||
#if MYNEWT_VAL(OS_CTX_SW_STACK_CHECK)
|
||||
os_stack_t *top;
|
||||
int i;
|
||||
|
||||
top = g_current_task->t_stacktop - g_current_task->t_stacksize;
|
||||
for (i = 0; i < MYNEWT_VAL(OS_CTX_SW_STACK_GUARD); i++) {
|
||||
assert(top[i] == OS_STACK_PATTERN);
|
||||
}
|
||||
#endif
|
||||
os_trace_task_start_exec(next_t->t_taskid);
|
||||
next_t->t_ctx_sw_cnt++;
|
||||
g_current_task->t_run_time += g_os_time - g_os_last_ctx_sw_time;
|
||||
g_os_last_ctx_sw_time = g_os_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched get current task
|
||||
*
|
||||
* Returns the currently running task. Note that this task may or may not be
|
||||
* the highest priority task ready to run.
|
||||
*
|
||||
*
|
||||
* @return struct os_task*
|
||||
*/
|
||||
struct os_task *
|
||||
os_sched_get_current_task(void)
|
||||
{
|
||||
return (g_current_task);
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched set current task
|
||||
*
|
||||
* Sets the currently running task to 't'. Note that this function simply sets
|
||||
* the global variable holding the currently running task. It does not perform
|
||||
* a context switch or change the os run or sleep list.
|
||||
*
|
||||
* @param t Pointer to currently running task.
|
||||
*/
|
||||
void
|
||||
os_sched_set_current_task(struct os_task *t)
|
||||
{
|
||||
g_current_task = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched
|
||||
*
|
||||
* Performs a context switch. When called, it will either find the highest
|
||||
* priority task ready to run if next_t is NULL (i.e. the head of the os run
|
||||
* list) or will schedule next_t as the task to run.
|
||||
*
|
||||
* @param next_t Task to run
|
||||
*/
|
||||
void
|
||||
os_sched(struct os_task *next_t)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
if (!next_t) {
|
||||
next_t = os_sched_next_task();
|
||||
}
|
||||
|
||||
os_arch_ctx_sw(next_t);
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched sleep
|
||||
*
|
||||
* Removes the task from the run list and puts it on the sleep list.
|
||||
*
|
||||
* @param t Task to put to sleep
|
||||
* @param nticks Number of ticks to put task to sleep
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* NOTE: must be called with interrupts disabled! This function does not call
|
||||
* the scheduler
|
||||
*/
|
||||
int
|
||||
os_sched_sleep(struct os_task *t, os_time_t nticks)
|
||||
{
|
||||
struct os_task *entry;
|
||||
|
||||
entry = NULL;
|
||||
|
||||
TAILQ_REMOVE(&g_os_run_list, t, t_os_list);
|
||||
t->t_state = OS_TASK_SLEEP;
|
||||
t->t_next_wakeup = os_time_get() + nticks;
|
||||
if (nticks == OS_TIMEOUT_NEVER) {
|
||||
t->t_flags |= OS_TASK_FLAG_NO_TIMEOUT;
|
||||
TAILQ_INSERT_TAIL(&g_os_sleep_list, t, t_os_list);
|
||||
} else {
|
||||
TAILQ_FOREACH(entry, &g_os_sleep_list, t_os_list) {
|
||||
if ((entry->t_flags & OS_TASK_FLAG_NO_TIMEOUT) ||
|
||||
OS_TIME_TICK_GT(entry->t_next_wakeup, t->t_next_wakeup)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry) {
|
||||
TAILQ_INSERT_BEFORE(entry, t, t_os_list);
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&g_os_sleep_list, t, t_os_list);
|
||||
}
|
||||
}
|
||||
|
||||
os_trace_task_stop_ready(t->t_taskid, OS_TASK_SLEEP);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched remove
|
||||
*
|
||||
* XXX
|
||||
* NOTE - This routine is currently experimental and not ready for common use
|
||||
*
|
||||
* Stops a task and removes it from the task list.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* NOTE: must be called with interrupts disabled! This function does not call
|
||||
* the scheduler
|
||||
*/
|
||||
int
|
||||
os_sched_remove(struct os_task *t)
|
||||
{
|
||||
|
||||
if (t->t_state == OS_TASK_SLEEP) {
|
||||
TAILQ_REMOVE(&g_os_sleep_list, t, t_os_list);
|
||||
} else if (t->t_state == OS_TASK_READY) {
|
||||
TAILQ_REMOVE(&g_os_run_list, t, t_os_list);
|
||||
}
|
||||
t->t_next_wakeup = 0;
|
||||
t->t_flags |= OS_TASK_FLAG_NO_TIMEOUT;
|
||||
|
||||
STAILQ_REMOVE(&g_os_task_list, t, os_task, t_os_task_list);
|
||||
|
||||
os_trace_task_stop_exec();
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched wakeup
|
||||
*
|
||||
* Called to wake up a task. Waking up a task consists of setting the task state
|
||||
* to READY and moving it from the sleep list to the run list.
|
||||
*
|
||||
* @param t Pointer to task to wake up.
|
||||
*
|
||||
* @return int
|
||||
*
|
||||
* NOTE: This function must be called with interrupts disabled.
|
||||
*/
|
||||
int
|
||||
os_sched_wakeup(struct os_task *t)
|
||||
{
|
||||
struct os_task_obj *os_obj;
|
||||
|
||||
assert(t->t_state == OS_TASK_SLEEP);
|
||||
|
||||
/* Remove self from object list if waiting on one */
|
||||
if (t->t_obj) {
|
||||
os_obj = (struct os_task_obj *)t->t_obj;
|
||||
assert(!SLIST_EMPTY(&os_obj->obj_head));
|
||||
SLIST_REMOVE(&os_obj->obj_head, t, os_task, t_obj_list);
|
||||
SLIST_NEXT(t, t_obj_list) = NULL;
|
||||
t->t_obj = NULL;
|
||||
}
|
||||
|
||||
/* Remove task from sleep list */
|
||||
t->t_state = OS_TASK_READY;
|
||||
t->t_next_wakeup = 0;
|
||||
t->t_flags &= ~OS_TASK_FLAG_NO_TIMEOUT;
|
||||
TAILQ_REMOVE(&g_os_sleep_list, t, t_os_list);
|
||||
os_sched_insert(t);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched os timer exp
|
||||
*
|
||||
* Called when the OS tick timer expires. Search the sleep list for any tasks
|
||||
* that need waking up. This occurs when the current OS time exceeds the next
|
||||
* wakeup time stored in the task. Any tasks that need waking up will be
|
||||
* removed from the sleep list and added to the run list.
|
||||
*
|
||||
*/
|
||||
void
|
||||
os_sched_os_timer_exp(void)
|
||||
{
|
||||
struct os_task *t;
|
||||
struct os_task *next;
|
||||
os_time_t now;
|
||||
os_sr_t sr;
|
||||
|
||||
now = os_time_get();
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/*
|
||||
* Wakeup any tasks that have their sleep timer expired
|
||||
*/
|
||||
t = TAILQ_FIRST(&g_os_sleep_list);
|
||||
while (t) {
|
||||
/* If task waiting forever, do not check next wakeup time */
|
||||
if (t->t_flags & OS_TASK_FLAG_NO_TIMEOUT) {
|
||||
break;
|
||||
}
|
||||
next = TAILQ_NEXT(t, t_os_list);
|
||||
if (OS_TIME_TICK_GEQ(now, t->t_next_wakeup)) {
|
||||
os_trace_task_start_ready(t->t_taskid);
|
||||
os_sched_wakeup(t);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
t = next;
|
||||
}
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the number of ticks until the first sleep timer expires.If there are
|
||||
* no such tasks then return OS_TIMEOUT_NEVER instead.
|
||||
*/
|
||||
os_time_t
|
||||
os_sched_wakeup_ticks(os_time_t now)
|
||||
{
|
||||
os_time_t rt;
|
||||
struct os_task *t;
|
||||
|
||||
OS_ASSERT_CRITICAL();
|
||||
|
||||
t = TAILQ_FIRST(&g_os_sleep_list);
|
||||
if (t == NULL || (t->t_flags & OS_TASK_FLAG_NO_TIMEOUT)) {
|
||||
rt = OS_TIMEOUT_NEVER;
|
||||
} else if (OS_TIME_TICK_GEQ(t->t_next_wakeup, now)) {
|
||||
rt = t->t_next_wakeup - now;
|
||||
} else {
|
||||
rt = 0; /* wakeup time was in the past */
|
||||
}
|
||||
return (rt);
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched next task
|
||||
*
|
||||
* Returns the task that we should be running. This is the task at the head
|
||||
* of the run list.
|
||||
*
|
||||
* NOTE: if you want to guarantee that the os run list does not change after
|
||||
* calling this function you have to call it with interrupts disabled.
|
||||
*
|
||||
* @return struct os_task*
|
||||
*/
|
||||
struct os_task *
|
||||
os_sched_next_task(void)
|
||||
{
|
||||
return (TAILQ_FIRST(&g_os_run_list));
|
||||
}
|
||||
|
||||
/**
|
||||
* os sched resort
|
||||
*
|
||||
* Resort a task that is in the ready list as its priority has
|
||||
* changed. If the task is not in the ready state, there is
|
||||
* nothing to do.
|
||||
*
|
||||
* @param t Pointer to task to insert back into ready to run
|
||||
* list.
|
||||
*
|
||||
* NOTE: this function expects interrupts to be disabled so they
|
||||
* are not disabled here.
|
||||
*/
|
||||
void
|
||||
os_sched_resort(struct os_task *t)
|
||||
{
|
||||
if (t->t_state == OS_TASK_READY) {
|
||||
TAILQ_REMOVE(&g_os_run_list, t, t_os_list);
|
||||
os_sched_insert(t);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSSched
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSSem Semaphores
|
||||
* @{
|
||||
*/
|
||||
|
||||
/* XXX:
|
||||
* 1) Should I check to see if we are within an ISR for some of these?
|
||||
* 2) Would I do anything different for os_sem_release() if we were in an
|
||||
* ISR when this was called?
|
||||
*/
|
||||
|
||||
/**
|
||||
* os sem initialize
|
||||
*
|
||||
* Initialize a semaphore
|
||||
*
|
||||
* @param sem Pointer to semaphore
|
||||
* tokens: # of tokens the semaphore should contain initially.
|
||||
*
|
||||
* @return os_error_t
|
||||
* OS_INVALID_PARM Semaphore passed in was NULL.
|
||||
* OS_OK no error.
|
||||
*/
|
||||
os_error_t
|
||||
os_sem_init(struct os_sem *sem, uint16_t tokens)
|
||||
{
|
||||
if (!sem) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
sem->sem_tokens = tokens;
|
||||
SLIST_FIRST(&sem->sem_head) = NULL;
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* os sem release
|
||||
*
|
||||
* Release a semaphore.
|
||||
*
|
||||
* @param sem Pointer to the semaphore to be released
|
||||
*
|
||||
* @return os_error_t
|
||||
* OS_INVALID_PARM Semaphore passed in was NULL.
|
||||
* OS_OK No error
|
||||
*/
|
||||
os_error_t
|
||||
os_sem_release(struct os_sem *sem)
|
||||
{
|
||||
int resched;
|
||||
os_sr_t sr;
|
||||
struct os_task *current;
|
||||
struct os_task *rdy;
|
||||
|
||||
/* OS must be started to release semaphores */
|
||||
if (!g_os_started) {
|
||||
return (OS_NOT_STARTED);
|
||||
}
|
||||
|
||||
/* Check for valid semaphore */
|
||||
if (!sem) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
/* Get current task */
|
||||
resched = 0;
|
||||
current = os_sched_get_current_task();
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/* Check if tasks are waiting for the semaphore */
|
||||
rdy = SLIST_FIRST(&sem->sem_head);
|
||||
if (rdy) {
|
||||
/* Clear flag that we are waiting on the semaphore; wake up task */
|
||||
rdy->t_flags &= ~OS_TASK_FLAG_SEM_WAIT;
|
||||
os_sched_wakeup(rdy);
|
||||
|
||||
/* Schedule if waiting task higher priority */
|
||||
if (current->t_prio > rdy->t_prio) {
|
||||
resched = 1;
|
||||
}
|
||||
} else {
|
||||
/* Add to the number of tokens */
|
||||
sem->sem_tokens++;
|
||||
}
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
/* Re-schedule if needed */
|
||||
if (resched) {
|
||||
os_sched(rdy);
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* os sem pend
|
||||
*
|
||||
* Pend (wait) for a semaphore.
|
||||
*
|
||||
* @param mu Pointer to semaphore.
|
||||
* @param timeout Timeout, in os ticks. A timeout of 0 means do
|
||||
* not wait if not available. A timeout of
|
||||
* 0xFFFFFFFF means wait forever.
|
||||
*
|
||||
*
|
||||
* @return os_error_t
|
||||
* OS_INVALID_PARM Semaphore passed in was NULL.
|
||||
* OS_TIMEOUT Semaphore was owned by another task and timeout=0
|
||||
* OS_OK no error.
|
||||
*/
|
||||
os_error_t
|
||||
os_sem_pend(struct os_sem *sem, uint32_t timeout)
|
||||
{
|
||||
os_sr_t sr;
|
||||
os_error_t rc;
|
||||
int sched;
|
||||
struct os_task *current;
|
||||
struct os_task *entry;
|
||||
struct os_task *last;
|
||||
|
||||
/* Check if OS is started */
|
||||
if (!g_os_started) {
|
||||
return (OS_NOT_STARTED);
|
||||
}
|
||||
|
||||
/* Check for valid semaphore */
|
||||
if (!sem) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
/* Assume we dont have to put task to sleep; get current task */
|
||||
sched = 0;
|
||||
current = os_sched_get_current_task();
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
|
||||
/*
|
||||
* If there is a token available, take it. If no token, either return
|
||||
* with error if timeout was 0 or put this task to sleep.
|
||||
*/
|
||||
if (sem->sem_tokens != 0) {
|
||||
sem->sem_tokens--;
|
||||
rc = OS_OK;
|
||||
} else if (timeout == 0) {
|
||||
rc = OS_TIMEOUT;
|
||||
} else {
|
||||
/* Silence gcc maybe-uninitialized warning. */
|
||||
rc = OS_OK;
|
||||
|
||||
/* Link current task to tasks waiting for semaphore */
|
||||
current->t_obj = sem;
|
||||
current->t_flags |= OS_TASK_FLAG_SEM_WAIT;
|
||||
last = NULL;
|
||||
if (!SLIST_EMPTY(&sem->sem_head)) {
|
||||
/* Insert in priority order */
|
||||
SLIST_FOREACH(entry, &sem->sem_head, t_obj_list) {
|
||||
if (current->t_prio < entry->t_prio) {
|
||||
break;
|
||||
}
|
||||
last = entry;
|
||||
}
|
||||
}
|
||||
|
||||
if (last) {
|
||||
SLIST_INSERT_AFTER(last, current, t_obj_list);
|
||||
} else {
|
||||
SLIST_INSERT_HEAD(&sem->sem_head, current, t_obj_list);
|
||||
}
|
||||
|
||||
/* We will put this task to sleep */
|
||||
sched = 1;
|
||||
os_sched_sleep(current, timeout);
|
||||
}
|
||||
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
if (sched) {
|
||||
os_sched(NULL);
|
||||
/* Check if we timed out or got the semaphore */
|
||||
if (current->t_flags & OS_TASK_FLAG_SEM_WAIT) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
current->t_flags &= ~OS_TASK_FLAG_SEM_WAIT;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
rc = OS_TIMEOUT;
|
||||
} else {
|
||||
rc = OS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @} OSSched
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* 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/os.h"
|
||||
#include "os/os_trace_api.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "../os/os_priv.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSTask Tasks
|
||||
* @{
|
||||
*/
|
||||
|
||||
uint8_t g_task_id;
|
||||
|
||||
struct os_task_stailq g_os_task_list;
|
||||
|
||||
static void
|
||||
_clear_stack(os_stack_t *stack_bottom, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
stack_bottom[i] = OS_STACK_PATTERN;
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t
|
||||
os_task_next_id(void)
|
||||
{
|
||||
uint8_t rc;
|
||||
os_sr_t sr;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
rc = g_task_id;
|
||||
g_task_id++;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of tasks initialized.
|
||||
*
|
||||
* @return number of tasks initialized
|
||||
*/
|
||||
uint8_t
|
||||
os_task_count(void)
|
||||
{
|
||||
return (g_task_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a task.
|
||||
*
|
||||
* This function initializes the task structure pointed to by t,
|
||||
* clearing and setting it's stack pointer, provides sane defaults
|
||||
* and sets the task as ready to run, and inserts it into the operating
|
||||
* system scheduler.
|
||||
*
|
||||
* @param t The task to initialize
|
||||
* @param name The name of the task to initialize
|
||||
* @param func The task function to call
|
||||
* @param arg The argument to pass to this task function
|
||||
* @param prio The priority at which to run this task
|
||||
* @param sanity_itvl The time at which this task should check in with the
|
||||
* sanity task. OS_WAIT_FOREVER means never check in
|
||||
* here.
|
||||
* @param stack_bottom A pointer to the bottom of a task's stack
|
||||
* @param stack_size The overall size of the task's stack.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
os_task_init(struct os_task *t, const char *name, os_task_func_t func,
|
||||
void *arg, uint8_t prio, os_time_t sanity_itvl,
|
||||
os_stack_t *stack_bottom, uint16_t stack_size)
|
||||
{
|
||||
struct os_sanity_check *sc;
|
||||
int rc;
|
||||
struct os_task *task;
|
||||
|
||||
memset(t, 0, sizeof(*t));
|
||||
|
||||
t->t_func = func;
|
||||
t->t_arg = arg;
|
||||
|
||||
t->t_taskid = os_task_next_id();
|
||||
t->t_prio = prio;
|
||||
|
||||
t->t_state = OS_TASK_READY;
|
||||
t->t_name = name;
|
||||
t->t_next_wakeup = 0;
|
||||
|
||||
rc = os_sanity_check_init(&t->t_sanity_check);
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (sanity_itvl != OS_WAIT_FOREVER) {
|
||||
sc = (struct os_sanity_check *) &t->t_sanity_check;
|
||||
sc->sc_checkin_itvl = sanity_itvl;
|
||||
|
||||
rc = os_sanity_check_register(sc);
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
_clear_stack(stack_bottom, stack_size);
|
||||
t->t_stacktop = &stack_bottom[stack_size];
|
||||
t->t_stacksize = stack_size;
|
||||
t->t_stackptr = os_arch_task_stack_init(t, t->t_stacktop,
|
||||
t->t_stacksize);
|
||||
|
||||
STAILQ_FOREACH(task, &g_os_task_list, t_os_task_list) {
|
||||
assert(t->t_prio != task->t_prio);
|
||||
}
|
||||
|
||||
/* insert this task into the task list */
|
||||
STAILQ_INSERT_TAIL(&g_os_task_list, t, t_os_task_list);
|
||||
|
||||
/* insert this task into the scheduler list */
|
||||
rc = os_sched_insert(t);
|
||||
if (rc != OS_OK) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
os_trace_task_info(t);
|
||||
|
||||
return (0);
|
||||
err:
|
||||
return (rc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Removes specified task
|
||||
* XXX
|
||||
* NOTE: This interface is currently experimental and not ready for common use
|
||||
*/
|
||||
int
|
||||
os_task_remove(struct os_task *t)
|
||||
{
|
||||
struct os_task *current;
|
||||
int rc;
|
||||
os_sr_t sr;
|
||||
|
||||
current = os_sched_get_current_task();
|
||||
/*
|
||||
* Can't suspend yourself
|
||||
*/
|
||||
if (t->t_taskid == current->t_taskid) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
/*
|
||||
* If state is not READY or SLEEP, assume task has not been initialized
|
||||
*/
|
||||
if (t->t_state != OS_TASK_READY && t->t_state != OS_TASK_SLEEP)
|
||||
{
|
||||
return OS_NOT_STARTED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disallow suspending tasks which are waiting on a lock
|
||||
*/
|
||||
if (t->t_flags & (OS_TASK_FLAG_SEM_WAIT | OS_TASK_FLAG_MUTEX_WAIT |
|
||||
OS_TASK_FLAG_EVQ_WAIT)) {
|
||||
return OS_EBUSY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disallowing suspending tasks which are holding a mutex
|
||||
*/
|
||||
if (t->t_lockcnt) {
|
||||
return OS_EBUSY;
|
||||
}
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
rc = os_sched_remove(t);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterate through tasks, and return the following information about them:
|
||||
*
|
||||
* - Priority
|
||||
* - Task ID
|
||||
* - State (ACTIVE, SLEEP)
|
||||
* - Total Stack Usage
|
||||
* - Stack Size
|
||||
* - Context Switch Count
|
||||
* - Runtime
|
||||
* - Last & Next Sanity checkin
|
||||
* - Task Name
|
||||
*
|
||||
* To get the first task in the list, call os_task_info_get_next() with a
|
||||
* NULL pointer in the prev argument, and os_task_info_get_next() will
|
||||
* return a pointer to the task structure, and fill out the os_task_info
|
||||
* structure pointed to by oti.
|
||||
*
|
||||
* To get the next task in the list, provide the task structure returned
|
||||
* by the previous call to os_task_info_get_next(), and os_task_info_get_next()
|
||||
* will fill out the task structure pointed to by oti again, and return
|
||||
* the next task in the list.
|
||||
*
|
||||
* @param prev The previous task returned by os_task_info_get_next(), or NULL
|
||||
* to begin iteration.
|
||||
* @param oti The OS task info structure to fill out.
|
||||
*
|
||||
* @return A pointer to the OS task that has been read, or NULL when finished
|
||||
* iterating through all tasks.
|
||||
*/
|
||||
struct os_task *
|
||||
os_task_info_get_next(const struct os_task *prev, struct os_task_info *oti)
|
||||
{
|
||||
struct os_task *next;
|
||||
os_stack_t *top;
|
||||
os_stack_t *bottom;
|
||||
|
||||
if (prev != NULL) {
|
||||
next = STAILQ_NEXT(prev, t_os_task_list);
|
||||
} else {
|
||||
next = STAILQ_FIRST(&g_os_task_list);
|
||||
}
|
||||
|
||||
if (next == NULL) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Otherwise, copy OS task information into the OTI structure, and
|
||||
* return 1, which means continue
|
||||
*/
|
||||
oti->oti_prio = next->t_prio;
|
||||
oti->oti_taskid = next->t_taskid;
|
||||
oti->oti_state = next->t_state;
|
||||
|
||||
top = next->t_stacktop;
|
||||
bottom = next->t_stacktop - next->t_stacksize;
|
||||
while (bottom < top) {
|
||||
if (*bottom != OS_STACK_PATTERN) {
|
||||
break;
|
||||
}
|
||||
++bottom;
|
||||
}
|
||||
|
||||
oti->oti_stkusage = (uint16_t) (next->t_stacktop - bottom);
|
||||
oti->oti_stksize = next->t_stacksize;
|
||||
oti->oti_cswcnt = next->t_ctx_sw_cnt;
|
||||
oti->oti_runtime = next->t_run_time;
|
||||
oti->oti_last_checkin = next->t_sanity_check.sc_checkin_last;
|
||||
oti->oti_next_checkin = next->t_sanity_check.sc_checkin_last +
|
||||
next->t_sanity_check.sc_checkin_itvl;
|
||||
strncpy(oti->oti_name, next->t_name, sizeof(oti->oti_name));
|
||||
|
||||
return (next);
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSTask
|
||||
* @} OSKernel
|
||||
*/
|
||||
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
* 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 "syscfg/syscfg.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "os/os.h"
|
||||
#include "os/queue.h"
|
||||
|
||||
/**
|
||||
* @addtogroup OSKernel
|
||||
* @{
|
||||
* @defgroup OSTime Time
|
||||
* @{
|
||||
*/
|
||||
|
||||
CTASSERT(sizeof(os_time_t) == 4);
|
||||
|
||||
#define OS_USEC_PER_TICK (1000000 / OS_TICKS_PER_SEC)
|
||||
|
||||
os_time_t g_os_time;
|
||||
|
||||
/*
|
||||
* Time-of-day collateral.
|
||||
*/
|
||||
static struct {
|
||||
os_time_t ostime;
|
||||
struct os_timeval uptime;
|
||||
struct os_timeval utctime;
|
||||
struct os_timezone timezone;
|
||||
} basetod;
|
||||
|
||||
static void
|
||||
os_deltatime(os_time_t delta, const struct os_timeval *base,
|
||||
struct os_timeval *result)
|
||||
{
|
||||
struct os_timeval tvdelta;
|
||||
|
||||
tvdelta.tv_sec = delta / OS_TICKS_PER_SEC;
|
||||
tvdelta.tv_usec = (delta % OS_TICKS_PER_SEC) * OS_USEC_PER_TICK;
|
||||
os_timeradd(base, &tvdelta, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current OS time in ticks
|
||||
*
|
||||
* @return OS time in ticks
|
||||
*/
|
||||
os_time_t
|
||||
os_time_get(void)
|
||||
{
|
||||
return (g_os_time);
|
||||
}
|
||||
|
||||
#if MYNEWT_VAL(OS_SCHEDULING)
|
||||
static void
|
||||
os_time_tick(int ticks)
|
||||
{
|
||||
os_sr_t sr;
|
||||
os_time_t delta, prev_os_time;
|
||||
|
||||
assert(ticks >= 0);
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
prev_os_time = g_os_time;
|
||||
g_os_time += ticks;
|
||||
|
||||
/*
|
||||
* Update 'basetod' when 'g_os_time' crosses the 0x00000000 and
|
||||
* 0x80000000 thresholds.
|
||||
*/
|
||||
if ((prev_os_time ^ g_os_time) >> 31) {
|
||||
delta = g_os_time - basetod.ostime;
|
||||
os_deltatime(delta, &basetod.uptime, &basetod.uptime);
|
||||
os_deltatime(delta, &basetod.utctime, &basetod.utctime);
|
||||
basetod.ostime = g_os_time;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move OS time forward ticks.
|
||||
*
|
||||
* @param ticks The number of ticks to move time forward.
|
||||
*/
|
||||
void
|
||||
os_time_advance(int ticks)
|
||||
{
|
||||
assert(ticks >= 0);
|
||||
|
||||
if (ticks > 0) {
|
||||
if (!os_started()) {
|
||||
g_os_time += ticks;
|
||||
} else {
|
||||
os_time_tick(ticks);
|
||||
os_callout_tick();
|
||||
os_sched_os_timer_exp();
|
||||
os_sched(NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void
|
||||
os_time_advance(int ticks)
|
||||
{
|
||||
g_os_time += ticks;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Puts the current task to sleep for the specified number of os ticks. There
|
||||
* is no delay if ticks is <= 0.
|
||||
*
|
||||
* @param osticks Number of ticks to delay (<= 0 means no delay).
|
||||
*/
|
||||
void
|
||||
os_time_delay(int32_t osticks)
|
||||
{
|
||||
os_sr_t sr;
|
||||
|
||||
if (osticks > 0) {
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
os_sched_sleep(os_sched_get_current_task(), (os_time_t)osticks);
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
os_sched(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the time of day. This does not modify os time, but rather just modifies
|
||||
* the offset by which we are tracking real time against os time.
|
||||
*
|
||||
* @param utctime A timeval representing the UTC time we are setting
|
||||
* @param tz The time-zone to apply against the utctime being set.
|
||||
*
|
||||
* @return 0 on success, non-zero on failure.
|
||||
*/
|
||||
int
|
||||
os_settimeofday(struct os_timeval *utctime, struct os_timezone *tz)
|
||||
{
|
||||
os_sr_t sr;
|
||||
os_time_t delta;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
if (utctime != NULL) {
|
||||
/*
|
||||
* Update all time-of-day base values.
|
||||
*/
|
||||
delta = os_time_get() - basetod.ostime;
|
||||
os_deltatime(delta, &basetod.uptime, &basetod.uptime);
|
||||
basetod.utctime = *utctime;
|
||||
basetod.ostime += delta;
|
||||
}
|
||||
|
||||
if (tz != NULL) {
|
||||
basetod.timezone = *tz;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current time of day. Returns the time of day in UTC
|
||||
* into the tv argument, and returns the timezone (if set) into
|
||||
* tz.
|
||||
*
|
||||
* @param tv The structure to put the UTC time of day into
|
||||
* @param tz The structure to put the timezone information into
|
||||
*
|
||||
* @return 0 on success, non-zero on failure
|
||||
*/
|
||||
int
|
||||
os_gettimeofday(struct os_timeval *tv, struct os_timezone *tz)
|
||||
{
|
||||
os_sr_t sr;
|
||||
os_time_t delta;
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
if (tv != NULL) {
|
||||
delta = os_time_get() - basetod.ostime;
|
||||
os_deltatime(delta, &basetod.utctime, tv);
|
||||
}
|
||||
|
||||
if (tz != NULL) {
|
||||
*tz = basetod.timezone;
|
||||
}
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get time since boot in microseconds.
|
||||
*
|
||||
* @return time since boot in microseconds
|
||||
*/
|
||||
int64_t
|
||||
os_get_uptime_usec(void)
|
||||
{
|
||||
struct os_timeval tv;
|
||||
os_time_t delta;
|
||||
os_sr_t sr;
|
||||
os_time_t ostime;
|
||||
|
||||
|
||||
OS_ENTER_CRITICAL(sr);
|
||||
tv = basetod.uptime;
|
||||
ostime = basetod.ostime;
|
||||
delta = os_time_get() - ostime;
|
||||
OS_EXIT_CRITICAL(sr);
|
||||
|
||||
os_deltatime(delta, &tv, &tv);
|
||||
|
||||
return(tv.tv_sec * 1000000 + tv.tv_usec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts milliseconds to OS ticks.
|
||||
*
|
||||
* @param ms The milliseconds input.
|
||||
* @param out_ticks The OS ticks output.
|
||||
*
|
||||
* @return 0 on success; OS_EINVAL if the result is too
|
||||
* large to fit in a uint32_t.
|
||||
*/
|
||||
int
|
||||
os_time_ms_to_ticks(uint32_t ms, uint32_t *out_ticks)
|
||||
{
|
||||
uint64_t ticks;
|
||||
|
||||
#if OS_TICKS_PER_SEC == 1000
|
||||
*out_ticks = ms;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
_Static_assert(OS_TICKS_PER_SEC <= UINT32_MAX,
|
||||
"OS_TICKS_PER_SEC must be <= UINT32_MAX");
|
||||
|
||||
ticks = (uint64_t)ms * OS_TICKS_PER_SEC / 1000;
|
||||
if (ticks > UINT32_MAX) {
|
||||
return OS_EINVAL;
|
||||
}
|
||||
|
||||
*out_ticks = ticks;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @} OSKernel
|
||||
* @} OSTime
|
||||
*/
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include "os/os_fault.h"
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "sysinit/sysinit.h"
|
||||
|
||||
static void
|
||||
sysinit_dflt_panic_cb(const char *file, int line, const char *func,
|
||||
const char *expr, const char *msg)
|
||||
{
|
||||
#if MYNEWT_VAL(SYSINIT_PANIC_MESSAGE)
|
||||
if (msg != NULL) {
|
||||
fprintf(stderr, "sysinit failure: %s\n", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
__assert_func(file, line, func, expr);
|
||||
}
|
||||
|
||||
sysinit_panic_fn *sysinit_panic_cb = sysinit_dflt_panic_cb;
|
||||
|
||||
uint8_t sysinit_active;
|
||||
|
||||
/**
|
||||
* Sets the sysinit panic function; i.e., the function which executes when
|
||||
* initialization fails. By default, a panic triggers a failed assertion.
|
||||
*/
|
||||
void
|
||||
sysinit_panic_set(sysinit_panic_fn *panic_cb)
|
||||
{
|
||||
sysinit_panic_cb = panic_cb;
|
||||
}
|
||||
|
||||
void
|
||||
sysinit_start(void)
|
||||
{
|
||||
sysinit_active = 1;
|
||||
}
|
||||
|
||||
void
|
||||
sysinit_end(void)
|
||||
{
|
||||
sysinit_active = 0;
|
||||
}
|
||||
@@ -0,0 +1,257 @@
|
||||
PROJECT_NAME := nimble_FreeRTOS_pca10040
|
||||
TARGETS := nrf52832_xxaa
|
||||
OUTPUT_DIRECTORY := _build
|
||||
|
||||
NRF5_SDK_ROOT ?= ./nrf5_sdk
|
||||
PROJ_ROOT := ../..
|
||||
|
||||
$(OUTPUT_DIRECTORY)/nrf52832_xxaa.out: \
|
||||
LINKER_SCRIPT := nimble_FreeRTOS_gcc_nrf52.ld
|
||||
|
||||
# Source files common to all targets
|
||||
SRC_FILES += \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/button/app_button.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/util/app_error.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/util/app_error_weak.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/timer/app_timer_freertos.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/util/app_util_platform.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/util/nrf_assert.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/util/sdk_errors.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/croutine.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/event_groups.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/portable/MemMang/heap_1.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/list.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/portable/GCC/nrf52/port.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/portable/CMSIS/nrf52/port_cmsis.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/queue.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/tasks.c \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/timers.c \
|
||||
$(NRF5_SDK_ROOT)/components/boards/boards.c \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/clock/nrf_drv_clock.c \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/bsp/bsp.c \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/bsp/bsp_nfc.c \
|
||||
$(NRF5_SDK_ROOT)/external/segger_rtt/RTT_Syscalls_GCC.c \
|
||||
$(NRF5_SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
|
||||
$(NRF5_SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
|
||||
$(NRF5_SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52.S \
|
||||
$(NRF5_SDK_ROOT)/components/toolchain/system_nrf52.c \
|
||||
./src/main.c \
|
||||
./src/ble_task.c \
|
||||
./src/os_port.c \
|
||||
./src/cmsis_nvic.c \
|
||||
./src/hal_timer.c \
|
||||
$(PROJ_ROOT)/porting/common/src/nimble_port.c \
|
||||
$(PROJ_ROOT)/porting/common/src/mem/mem.c \
|
||||
$(PROJ_ROOT)/porting/common/src/os/endian.c \
|
||||
$(PROJ_ROOT)/porting/common/src/os/os_cputime.c \
|
||||
$(PROJ_ROOT)/porting/common/src/os/os_cputime_pwr2.c \
|
||||
$(PROJ_ROOT)/porting/common/src/os/os_mbuf.c \
|
||||
$(PROJ_ROOT)/porting/common/src/os/os_mempool.c \
|
||||
$(PROJ_ROOT)/porting/common/src/os/os_msys_init.c \
|
||||
$(PROJ_ROOT)/porting/common/src/sysinit/sysinit.c \
|
||||
$(PROJ_ROOT)/nimble/src/ble_util.c \
|
||||
$(PROJ_ROOT)/nimble/src/hci_common.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_att_clt.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_att_cmd.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_att.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_att_svr.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_eddystone.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_gap.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_gattc.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_gatts_lcl.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_gatts.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_adv.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_atomic.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_cfg.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_conn.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_dbg.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_hci_cmd.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_hci_evt.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_hci.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_hci_util.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_id.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_log.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_mbuf.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_misc.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_pvcy.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_hs_startup.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_ibeacon.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_l2cap_coc.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_l2cap.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_l2cap_sig_cmd.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_l2cap_sig.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_monitor.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_sm_alg.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_sm_cmd.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_sm_lgcy.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_sm.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_sm_sc.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_store.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_store_util.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_uuid.c \
|
||||
$(PROJ_ROOT)/nimble/host/src/ble_uuid.c \
|
||||
$(PROJ_ROOT)/nimble/host/services/ans/src/ble_svc_ans.c \
|
||||
$(PROJ_ROOT)/nimble/host/services/gap/src/ble_svc_gap.c \
|
||||
$(PROJ_ROOT)/nimble/host/services/gatt/src/ble_svc_gatt.c \
|
||||
$(PROJ_ROOT)/nimble/host/services/ias/src/ble_svc_ias.c \
|
||||
$(PROJ_ROOT)/nimble/host/services/lls/src/ble_svc_lls.c \
|
||||
$(PROJ_ROOT)/nimble/host/services/tps/src/ble_svc_tps.c \
|
||||
$(PROJ_ROOT)/nimble/host/store/ram/src/ble_store_ram.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_sched.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_xcvr.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_whitelist.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_ctrl.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_hci.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_supp_cmd.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_adv.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_conn.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_resolv.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_conn_hci.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_rand.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_scan.c \
|
||||
$(PROJ_ROOT)/nimble/controller/src/ble_ll_hci_ev.c \
|
||||
$(PROJ_ROOT)/nimble/transport/ram/src/ble_hci_ram.c \
|
||||
$(PROJ_ROOT)/nimble/drivers/nrf52/src/ble_hw.c \
|
||||
$(PROJ_ROOT)/nimble/drivers/nrf52/src/ble_phy.c \
|
||||
$(PROJ_ROOT)/tinycrypt/src/aes_decrypt.c \
|
||||
$(PROJ_ROOT)/tinycrypt/src/aes_encrypt.c \
|
||||
$(PROJ_ROOT)/tinycrypt/src/cmac_mode.c \
|
||||
$(PROJ_ROOT)/tinycrypt/src/ecc.c \
|
||||
$(PROJ_ROOT)/tinycrypt/src/ecc_dh.c \
|
||||
$(PROJ_ROOT)/tinycrypt/src/utils.c \
|
||||
|
||||
# Include folders common to all targets
|
||||
INC_FOLDERS += \
|
||||
./config \
|
||||
$(NRF5_SDK_ROOT)/components \
|
||||
$(NRF5_SDK_ROOT)/components/toolchain/cmsis/include \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/source/include \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/config \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/util \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/uart \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/bsp \
|
||||
$(NRF5_SDK_ROOT)/components/device \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/log \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/button \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/timer \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/portable/CMSIS/nrf52 \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/gpiote \
|
||||
$(NRF5_SDK_ROOT)/external/segger_rtt \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
|
||||
$(NRF5_SDK_ROOT)/components/boards \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/hal \
|
||||
$(NRF5_SDK_ROOT)/components/toolchain/gcc \
|
||||
$(NRF5_SDK_ROOT)/components/toolchain \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/common \
|
||||
$(NRF5_SDK_ROOT)/components/drivers_nrf/clock \
|
||||
$(NRF5_SDK_ROOT)/external/freertos/portable/GCC/nrf52 \
|
||||
$(NRF5_SDK_ROOT)/components/libraries/log/src \
|
||||
./include \
|
||||
$(PROJ_ROOT)/porting/common/include \
|
||||
$(PROJ_ROOT)/nimble/include \
|
||||
$(PROJ_ROOT)/nimble/host/include \
|
||||
$(PROJ_ROOT)/nimble/host/mesh/include \
|
||||
$(PROJ_ROOT)/nimble/host/services/ans/include \
|
||||
$(PROJ_ROOT)/nimble/host/services/gap/include \
|
||||
$(PROJ_ROOT)/nimble/host/services/gatt/include \
|
||||
$(PROJ_ROOT)/nimble/host/services/ias/include \
|
||||
$(PROJ_ROOT)/nimble/host/services/lls/include \
|
||||
$(PROJ_ROOT)/nimble/host/services/tps/include \
|
||||
$(PROJ_ROOT)/nimble/host/store/ram/include \
|
||||
$(PROJ_ROOT)/nimble/controller/include \
|
||||
$(PROJ_ROOT)/nimble/transport/ram/include \
|
||||
$(PROJ_ROOT)/nimble/drivers/nrf52/include \
|
||||
$(PROJ_ROOT)/tinycrypt/include \
|
||||
|
||||
# Libraries common to all targets
|
||||
LIB_FILES += \
|
||||
|
||||
# C flags common to all targets
|
||||
CFLAGS += -DNRF52_PAN_12
|
||||
CFLAGS += -DNRF52_PAN_15
|
||||
CFLAGS += -DNRF52_PAN_58
|
||||
CFLAGS += -DFREERTOS
|
||||
CFLAGS += -DNRF52_PAN_20
|
||||
CFLAGS += -DNRF52_PAN_54
|
||||
CFLAGS += -DNRF52
|
||||
CFLAGS += -DNRF52_PAN_51
|
||||
CFLAGS += -DNRF52_PAN_36
|
||||
CFLAGS += -DCONFIG_GPIO_AS_PINRESET
|
||||
CFLAGS += -DNRF52_PAN_64
|
||||
CFLAGS += -DNRF52_PAN_55
|
||||
CFLAGS += -DBOARD_PCA10040
|
||||
CFLAGS += -DNRF52_PAN_31
|
||||
CFLAGS += -DNRF52832
|
||||
CFLAGS += -mcpu=cortex-m4
|
||||
CFLAGS += -mthumb -mabi=aapcs
|
||||
CFLAGS += -Wall -Werror -Og -g3
|
||||
CFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
# keep every function in separate section, this allows linker to discard unused ones
|
||||
CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
|
||||
CFLAGS += -fno-builtin --short-enums
|
||||
|
||||
# C++ flags common to all targets
|
||||
CXXFLAGS += \
|
||||
|
||||
# Assembler flags common to all targets
|
||||
ASMFLAGS += -x assembler-with-cpp
|
||||
ASMFLAGS += -DNRF52_PAN_12
|
||||
ASMFLAGS += -DNRF52_PAN_15
|
||||
ASMFLAGS += -DNRF52_PAN_58
|
||||
ASMFLAGS += -DFREERTOS
|
||||
ASMFLAGS += -DNRF52_PAN_20
|
||||
ASMFLAGS += -DNRF52_PAN_54
|
||||
ASMFLAGS += -DNRF52
|
||||
ASMFLAGS += -DNRF52_PAN_51
|
||||
ASMFLAGS += -DNRF52_PAN_36
|
||||
ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
|
||||
ASMFLAGS += -DNRF52_PAN_64
|
||||
ASMFLAGS += -DNRF52_PAN_55
|
||||
ASMFLAGS += -DBOARD_PCA10040
|
||||
ASMFLAGS += -DNRF52_PAN_31
|
||||
ASMFLAGS += -DNRF52832
|
||||
|
||||
# Linker flags
|
||||
LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
|
||||
LDFLAGS += -mcpu=cortex-m4
|
||||
LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
|
||||
# let linker to dump unused sections
|
||||
LDFLAGS += -Wl,--gc-sections
|
||||
# use newlib in nano version
|
||||
LDFLAGS += --specs=nano.specs -lc -lnosys
|
||||
|
||||
|
||||
.PHONY: $(TARGETS) default all clean help flash
|
||||
|
||||
# Default target - first one defined
|
||||
default: nrf52832_xxaa
|
||||
|
||||
# Print all targets that can be built
|
||||
help:
|
||||
@echo following targets are available:
|
||||
@echo nrf52832_xxaa
|
||||
|
||||
TEMPLATE_PATH := $(NRF5_SDK_ROOT)/components/toolchain/gcc
|
||||
|
||||
include $(TEMPLATE_PATH)/Makefile.common
|
||||
|
||||
$(foreach target, $(TARGETS), $(call define_target, $(target)))
|
||||
|
||||
# Flash the program
|
||||
flash: $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex
|
||||
@echo Flashing: $<
|
||||
nrfjprog --program $< -f nrf52 --sectorerase
|
||||
nrfjprog --reset -f nrf52
|
||||
|
||||
erase:
|
||||
nrfjprog --eraseall -f nrf52
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
FreeRTOS V8.0.1 - Copyright (C) 2014 Real Time Engineers Ltd.
|
||||
All rights reserved
|
||||
|
||||
VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* FreeRTOS provides completely free yet professionally developed, *
|
||||
* robust, strictly quality controlled, supported, and cross *
|
||||
* platform software that has become a de facto standard. *
|
||||
* *
|
||||
* Help yourself get started quickly and support the FreeRTOS *
|
||||
* project by purchasing a FreeRTOS tutorial book, reference *
|
||||
* manual, or both from: http://www.FreeRTOS.org/Documentation *
|
||||
* *
|
||||
* Thank you! *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
This file is part of the FreeRTOS distribution.
|
||||
|
||||
FreeRTOS is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License (version 2) as published by the
|
||||
Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception.
|
||||
|
||||
>>! NOTE: The modification to the GPL is included to allow you to !<<
|
||||
>>! distribute a combined work that includes FreeRTOS without being !<<
|
||||
>>! obliged to provide the source code for proprietary components !<<
|
||||
>>! outside of the FreeRTOS kernel. !<<
|
||||
|
||||
FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. Full license text is available from the following
|
||||
link: http://www.freertos.org/a00114.html
|
||||
|
||||
1 tab == 4 spaces!
|
||||
|
||||
***************************************************************************
|
||||
* *
|
||||
* Having a problem? Start by reading the FAQ "My application does *
|
||||
* not run, what could be wrong?" *
|
||||
* *
|
||||
* http://www.FreeRTOS.org/FAQHelp.html *
|
||||
* *
|
||||
***************************************************************************
|
||||
|
||||
http://www.FreeRTOS.org - Documentation, books, training, latest versions,
|
||||
license and Real Time Engineers Ltd. contact details.
|
||||
|
||||
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
|
||||
including FreeRTOS+Trace - an indispensable productivity tool, a DOS
|
||||
compatible FAT file system, and our tiny thread aware UDP/IP stack.
|
||||
|
||||
http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High
|
||||
Integrity Systems to sell under the OpenRTOS brand. Low cost OpenRTOS
|
||||
licenses offer ticketed support, indemnification and middleware.
|
||||
|
||||
http://www.SafeRTOS.com - High Integrity Systems also provide a safety
|
||||
engineered and independently SIL3 certified version for use in safety and
|
||||
mission critical applications that require provable dependability.
|
||||
|
||||
1 tab == 4 spaces!
|
||||
*/
|
||||
|
||||
|
||||
#ifndef FREERTOS_CONFIG_H
|
||||
#define FREERTOS_CONFIG_H
|
||||
|
||||
#ifdef SOFTDEVICE_PRESENT
|
||||
#include "nrf_soc.h"
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Possible configurations for system timer
|
||||
*/
|
||||
#define FREERTOS_USE_RTC 0 /**< Use real time clock for the system */
|
||||
#define FREERTOS_USE_SYSTICK 1 /**< Use SysTick timer for system */
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Application specific definitions.
|
||||
*
|
||||
* These definitions should be adjusted for your particular hardware and
|
||||
* application requirements.
|
||||
*
|
||||
* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
|
||||
* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
|
||||
*
|
||||
* See http://www.freertos.org/a00110.html.
|
||||
*----------------------------------------------------------*/
|
||||
|
||||
#define configTICK_SOURCE FREERTOS_USE_RTC
|
||||
|
||||
#define configUSE_PREEMPTION 1
|
||||
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
|
||||
#define configUSE_TICKLESS_IDLE 1
|
||||
#define configUSE_TICKLESS_IDLE_SIMPLE_DEBUG 1 /* See into vPortSuppressTicksAndSleep source code for explanation */
|
||||
#define configCPU_CLOCK_HZ ( SystemCoreClock )
|
||||
#define configTICK_RATE_HZ 1000
|
||||
#define configMAX_PRIORITIES ( 3 )
|
||||
#define configMINIMAL_STACK_SIZE ( 60 )
|
||||
#define configTOTAL_HEAP_SIZE ( 6144 )
|
||||
#define configMAX_TASK_NAME_LEN ( 4 )
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
#define configUSE_MUTEXES 1
|
||||
#define configUSE_RECURSIVE_MUTEXES 1
|
||||
#define configUSE_COUNTING_SEMAPHORES 1
|
||||
#define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
|
||||
#define configQUEUE_REGISTRY_SIZE 2
|
||||
#define configUSE_QUEUE_SETS 0
|
||||
#define configUSE_TIME_SLICING 0
|
||||
#define configUSE_NEWLIB_REENTRANT 0
|
||||
#define configENABLE_BACKWARD_COMPATIBILITY 1
|
||||
|
||||
/* Hook function related definitions. */
|
||||
#define configUSE_IDLE_HOOK 0
|
||||
#define configUSE_TICK_HOOK 0
|
||||
#define configCHECK_FOR_STACK_OVERFLOW 0
|
||||
#define configUSE_MALLOC_FAILED_HOOK 0
|
||||
|
||||
/* Run time and task stats gathering related definitions. */
|
||||
#define configGENERATE_RUN_TIME_STATS 0
|
||||
#define configUSE_TRACE_FACILITY 0
|
||||
#define configUSE_STATS_FORMATTING_FUNCTIONS 0
|
||||
|
||||
/* Co-routine definitions. */
|
||||
#define configUSE_CO_ROUTINES 0
|
||||
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
|
||||
|
||||
/* Software timer definitions. */
|
||||
#define configUSE_TIMERS 1
|
||||
#define configTIMER_TASK_PRIORITY ( 2 )
|
||||
#define configTIMER_QUEUE_LENGTH 32
|
||||
#define configTIMER_TASK_STACK_DEPTH ( 80 )
|
||||
|
||||
/* Tickless Idle configuration. */
|
||||
#define configEXPECTED_IDLE_TIME_BEFORE_SLEEP 2
|
||||
|
||||
/* Tickless idle/low power functionality. */
|
||||
|
||||
|
||||
/* Define to trap errors during development. */
|
||||
#if defined(DEBUG_NRF) || defined(DEBUG_NRF_USER)
|
||||
#define configASSERT( x ) ASSERT(x)
|
||||
#endif
|
||||
|
||||
/* FreeRTOS MPU specific definitions. */
|
||||
#define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 1
|
||||
|
||||
/* Optional functions - most linkers will remove unused functions anyway. */
|
||||
#define INCLUDE_vTaskPrioritySet 1
|
||||
#define INCLUDE_uxTaskPriorityGet 1
|
||||
#define INCLUDE_vTaskDelete 1
|
||||
#define INCLUDE_vTaskSuspend 1
|
||||
#define INCLUDE_xResumeFromISR 1
|
||||
#define INCLUDE_vTaskDelayUntil 1
|
||||
#define INCLUDE_vTaskDelay 1
|
||||
#define INCLUDE_xTaskGetSchedulerState 1
|
||||
#define INCLUDE_xTaskGetCurrentTaskHandle 1
|
||||
#define INCLUDE_uxTaskGetStackHighWaterMark 1
|
||||
#define INCLUDE_xTaskGetIdleTaskHandle 1
|
||||
#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1
|
||||
#define INCLUDE_pcTaskGetTaskName 1
|
||||
#define INCLUDE_eTaskGetState 1
|
||||
#define INCLUDE_xEventGroupSetBitFromISR 1
|
||||
#define INCLUDE_xTimerPendFunctionCall 1
|
||||
|
||||
/* The lowest interrupt priority that can be used in a call to a "set priority"
|
||||
function. */
|
||||
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
|
||||
|
||||
/* The highest interrupt priority that can be used by any interrupt service
|
||||
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
|
||||
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
|
||||
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
|
||||
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 1
|
||||
|
||||
/* Interrupt priorities used by the kernel port layer itself. These are generic
|
||||
to all Cortex-M ports, and do not rely on any particular library functions. */
|
||||
#define configKERNEL_INTERRUPT_PRIORITY configLIBRARY_LOWEST_INTERRUPT_PRIORITY
|
||||
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
|
||||
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
|
||||
#define configMAX_SYSCALL_INTERRUPT_PRIORITY configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY
|
||||
|
||||
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
|
||||
standard names - or at least those used in the unmodified vector table. */
|
||||
|
||||
#define vPortSVCHandler SVC_Handler
|
||||
#define xPortPendSVHandler PendSV_Handler
|
||||
|
||||
|
||||
/*-----------------------------------------------------------
|
||||
* Settings that are generated automatically
|
||||
* basing on the settings above
|
||||
*/
|
||||
#if (configTICK_SOURCE == FREERTOS_USE_SYSTICK)
|
||||
// do not define configSYSTICK_CLOCK_HZ for SysTick to be configured automatically
|
||||
// to CPU clock source
|
||||
#define xPortSysTickHandler SysTick_Handler
|
||||
#elif (configTICK_SOURCE == FREERTOS_USE_RTC)
|
||||
#define configSYSTICK_CLOCK_HZ ( 32768UL )
|
||||
#define xPortSysTickHandler RTC1_IRQHandler
|
||||
#else
|
||||
#error Unsupported configTICK_SOURCE value
|
||||
#endif
|
||||
|
||||
/* Code below should be only used by the compiler, and not the assembler. */
|
||||
#if !(defined(__ASSEMBLY__) || defined(__ASSEMBLER__))
|
||||
#include "nrf.h"
|
||||
#include "nrf_assert.h"
|
||||
|
||||
/* This part of definitions may be problematic in assembly - it uses definitions from files that are not assembly compatible. */
|
||||
/* Cortex-M specific definitions. */
|
||||
#ifdef __NVIC_PRIO_BITS
|
||||
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
|
||||
#define configPRIO_BITS __NVIC_PRIO_BITS
|
||||
#else
|
||||
#error "This port requires __NVIC_PRIO_BITS to be defined"
|
||||
#endif
|
||||
|
||||
/* Access to current system core clock is required only if we are ticking the system by systimer */
|
||||
#if (configTICK_SOURCE == FREERTOS_USE_SYSTICK)
|
||||
#include <stdint.h>
|
||||
extern uint32_t SystemCoreClock;
|
||||
#endif
|
||||
#endif /* !assembler */
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
@@ -0,0 +1,699 @@
|
||||
|
||||
|
||||
#ifndef SDK_CONFIG_H
|
||||
#define SDK_CONFIG_H
|
||||
// <<< Use Configuration Wizard in Context Menu >>>\n
|
||||
#ifdef USE_APP_CONFIG
|
||||
#include "app_config.h"
|
||||
#endif
|
||||
// <h> nRF_Drivers
|
||||
|
||||
//==========================================================
|
||||
// <e> CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
|
||||
//==========================================================
|
||||
#ifndef CLOCK_ENABLED
|
||||
#define CLOCK_ENABLED 1
|
||||
#endif
|
||||
#if CLOCK_ENABLED
|
||||
// <o> CLOCK_CONFIG_XTAL_FREQ - HF XTAL Frequency
|
||||
|
||||
// <0=> Default (64 MHz)
|
||||
|
||||
#ifndef CLOCK_CONFIG_XTAL_FREQ
|
||||
#define CLOCK_CONFIG_XTAL_FREQ 0
|
||||
#endif
|
||||
|
||||
// <o> CLOCK_CONFIG_LF_SRC - LF Clock Source
|
||||
|
||||
// <0=> RC
|
||||
// <1=> XTAL
|
||||
// <2=> Synth
|
||||
|
||||
#ifndef CLOCK_CONFIG_LF_SRC
|
||||
#define CLOCK_CONFIG_LF_SRC 1
|
||||
#endif
|
||||
|
||||
// <o> CLOCK_CONFIG_IRQ_PRIORITY - Interrupt priority
|
||||
|
||||
|
||||
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
|
||||
// <0=> 0 (highest)
|
||||
// <1=> 1
|
||||
// <2=> 2
|
||||
// <3=> 3
|
||||
// <4=> 4
|
||||
// <5=> 5
|
||||
// <6=> 6
|
||||
// <7=> 7
|
||||
|
||||
#ifndef CLOCK_CONFIG_IRQ_PRIORITY
|
||||
#define CLOCK_CONFIG_IRQ_PRIORITY 7
|
||||
#endif
|
||||
|
||||
// <e> CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module.
|
||||
//==========================================================
|
||||
#ifndef CLOCK_CONFIG_LOG_ENABLED
|
||||
#define CLOCK_CONFIG_LOG_ENABLED 0
|
||||
#endif
|
||||
#if CLOCK_CONFIG_LOG_ENABLED
|
||||
// <o> CLOCK_CONFIG_LOG_LEVEL - Default Severity level
|
||||
|
||||
// <0=> Off
|
||||
// <1=> Error
|
||||
// <2=> Warning
|
||||
// <3=> Info
|
||||
// <4=> Debug
|
||||
|
||||
#ifndef CLOCK_CONFIG_LOG_LEVEL
|
||||
#define CLOCK_CONFIG_LOG_LEVEL 3
|
||||
#endif
|
||||
|
||||
// <o> CLOCK_CONFIG_INFO_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef CLOCK_CONFIG_INFO_COLOR
|
||||
#define CLOCK_CONFIG_INFO_COLOR 0
|
||||
#endif
|
||||
|
||||
// <o> CLOCK_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef CLOCK_CONFIG_DEBUG_COLOR
|
||||
#define CLOCK_CONFIG_DEBUG_COLOR 0
|
||||
#endif
|
||||
|
||||
#endif //CLOCK_CONFIG_LOG_ENABLED
|
||||
// </e>
|
||||
|
||||
#endif //CLOCK_ENABLED
|
||||
// </e>
|
||||
|
||||
// <e> GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver
|
||||
//==========================================================
|
||||
#ifndef GPIOTE_ENABLED
|
||||
#define GPIOTE_ENABLED 1
|
||||
#endif
|
||||
#if GPIOTE_ENABLED
|
||||
// <o> GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins
|
||||
#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
|
||||
#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4
|
||||
#endif
|
||||
|
||||
// <o> GPIOTE_CONFIG_IRQ_PRIORITY - Interrupt priority
|
||||
|
||||
|
||||
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
|
||||
// <0=> 0 (highest)
|
||||
// <1=> 1
|
||||
// <2=> 2
|
||||
// <3=> 3
|
||||
// <4=> 4
|
||||
// <5=> 5
|
||||
// <6=> 6
|
||||
// <7=> 7
|
||||
|
||||
#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
|
||||
#define GPIOTE_CONFIG_IRQ_PRIORITY 7
|
||||
#endif
|
||||
|
||||
// <e> GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
|
||||
//==========================================================
|
||||
#ifndef GPIOTE_CONFIG_LOG_ENABLED
|
||||
#define GPIOTE_CONFIG_LOG_ENABLED 0
|
||||
#endif
|
||||
#if GPIOTE_CONFIG_LOG_ENABLED
|
||||
// <o> GPIOTE_CONFIG_LOG_LEVEL - Default Severity level
|
||||
|
||||
// <0=> Off
|
||||
// <1=> Error
|
||||
// <2=> Warning
|
||||
// <3=> Info
|
||||
// <4=> Debug
|
||||
|
||||
#ifndef GPIOTE_CONFIG_LOG_LEVEL
|
||||
#define GPIOTE_CONFIG_LOG_LEVEL 3
|
||||
#endif
|
||||
|
||||
// <o> GPIOTE_CONFIG_INFO_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef GPIOTE_CONFIG_INFO_COLOR
|
||||
#define GPIOTE_CONFIG_INFO_COLOR 0
|
||||
#endif
|
||||
|
||||
// <o> GPIOTE_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef GPIOTE_CONFIG_DEBUG_COLOR
|
||||
#define GPIOTE_CONFIG_DEBUG_COLOR 0
|
||||
#endif
|
||||
|
||||
#endif //GPIOTE_CONFIG_LOG_ENABLED
|
||||
// </e>
|
||||
|
||||
#endif //GPIOTE_ENABLED
|
||||
// </e>
|
||||
|
||||
// <e> PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common - Peripheral drivers common module
|
||||
//==========================================================
|
||||
#ifndef PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
#define PERIPHERAL_RESOURCE_SHARING_ENABLED 0
|
||||
#endif
|
||||
#if PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
// <e> COMMON_CONFIG_LOG_ENABLED - Enables logging in the module.
|
||||
//==========================================================
|
||||
#ifndef COMMON_CONFIG_LOG_ENABLED
|
||||
#define COMMON_CONFIG_LOG_ENABLED 0
|
||||
#endif
|
||||
#if COMMON_CONFIG_LOG_ENABLED
|
||||
// <o> COMMON_CONFIG_LOG_LEVEL - Default Severity level
|
||||
|
||||
// <0=> Off
|
||||
// <1=> Error
|
||||
// <2=> Warning
|
||||
// <3=> Info
|
||||
// <4=> Debug
|
||||
|
||||
#ifndef COMMON_CONFIG_LOG_LEVEL
|
||||
#define COMMON_CONFIG_LOG_LEVEL 3
|
||||
#endif
|
||||
|
||||
// <o> COMMON_CONFIG_INFO_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef COMMON_CONFIG_INFO_COLOR
|
||||
#define COMMON_CONFIG_INFO_COLOR 0
|
||||
#endif
|
||||
|
||||
// <o> COMMON_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef COMMON_CONFIG_DEBUG_COLOR
|
||||
#define COMMON_CONFIG_DEBUG_COLOR 0
|
||||
#endif
|
||||
|
||||
#endif //COMMON_CONFIG_LOG_ENABLED
|
||||
// </e>
|
||||
|
||||
#endif //PERIPHERAL_RESOURCE_SHARING_ENABLED
|
||||
// </e>
|
||||
|
||||
// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver
|
||||
//==========================================================
|
||||
#ifndef UART_ENABLED
|
||||
#define UART_ENABLED 1
|
||||
#endif
|
||||
#if UART_ENABLED
|
||||
// <o> UART_DEFAULT_CONFIG_HWFC - Hardware Flow Control
|
||||
|
||||
// <0=> Disabled
|
||||
// <1=> Enabled
|
||||
|
||||
#ifndef UART_DEFAULT_CONFIG_HWFC
|
||||
#define UART_DEFAULT_CONFIG_HWFC 0
|
||||
#endif
|
||||
|
||||
// <o> UART_DEFAULT_CONFIG_PARITY - Parity
|
||||
|
||||
// <0=> Excluded
|
||||
// <14=> Included
|
||||
|
||||
#ifndef UART_DEFAULT_CONFIG_PARITY
|
||||
#define UART_DEFAULT_CONFIG_PARITY 0
|
||||
#endif
|
||||
|
||||
// <o> UART_DEFAULT_CONFIG_BAUDRATE - Default Baudrate
|
||||
|
||||
// <323584=> 1200 baud
|
||||
// <643072=> 2400 baud
|
||||
// <1290240=> 4800 baud
|
||||
// <2576384=> 9600 baud
|
||||
// <3862528=> 14400 baud
|
||||
// <5152768=> 19200 baud
|
||||
// <7716864=> 28800 baud
|
||||
// <10289152=> 38400 baud
|
||||
// <15400960=> 57600 baud
|
||||
// <20615168=> 76800 baud
|
||||
// <30801920=> 115200 baud
|
||||
// <61865984=> 230400 baud
|
||||
// <67108864=> 250000 baud
|
||||
// <121634816=> 460800 baud
|
||||
// <251658240=> 921600 baud
|
||||
// <268435456=> 57600 baud
|
||||
|
||||
#ifndef UART_DEFAULT_CONFIG_BAUDRATE
|
||||
#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
|
||||
#endif
|
||||
|
||||
// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY - Interrupt priority
|
||||
|
||||
|
||||
// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
|
||||
// <0=> 0 (highest)
|
||||
// <1=> 1
|
||||
// <2=> 2
|
||||
// <3=> 3
|
||||
// <4=> 4
|
||||
// <5=> 5
|
||||
// <6=> 6
|
||||
// <7=> 7
|
||||
|
||||
#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
|
||||
#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 7
|
||||
#endif
|
||||
|
||||
// <q> UART_EASY_DMA_SUPPORT - Driver supporting EasyDMA
|
||||
|
||||
|
||||
#ifndef UART_EASY_DMA_SUPPORT
|
||||
#define UART_EASY_DMA_SUPPORT 1
|
||||
#endif
|
||||
|
||||
// <q> UART_LEGACY_SUPPORT - Driver supporting Legacy mode
|
||||
|
||||
|
||||
#ifndef UART_LEGACY_SUPPORT
|
||||
#define UART_LEGACY_SUPPORT 1
|
||||
#endif
|
||||
|
||||
// <e> UART0_ENABLED - Enable UART0 instance
|
||||
//==========================================================
|
||||
#ifndef UART0_ENABLED
|
||||
#define UART0_ENABLED 1
|
||||
#endif
|
||||
#if UART0_ENABLED
|
||||
// <q> UART0_CONFIG_USE_EASY_DMA - Default setting for using EasyDMA
|
||||
|
||||
|
||||
#ifndef UART0_CONFIG_USE_EASY_DMA
|
||||
#define UART0_CONFIG_USE_EASY_DMA 1
|
||||
#endif
|
||||
|
||||
#endif //UART0_ENABLED
|
||||
// </e>
|
||||
|
||||
// <e> UART_CONFIG_LOG_ENABLED - Enables logging in the module.
|
||||
//==========================================================
|
||||
#ifndef UART_CONFIG_LOG_ENABLED
|
||||
#define UART_CONFIG_LOG_ENABLED 0
|
||||
#endif
|
||||
#if UART_CONFIG_LOG_ENABLED
|
||||
// <o> UART_CONFIG_LOG_LEVEL - Default Severity level
|
||||
|
||||
// <0=> Off
|
||||
// <1=> Error
|
||||
// <2=> Warning
|
||||
// <3=> Info
|
||||
// <4=> Debug
|
||||
|
||||
#ifndef UART_CONFIG_LOG_LEVEL
|
||||
#define UART_CONFIG_LOG_LEVEL 3
|
||||
#endif
|
||||
|
||||
// <o> UART_CONFIG_INFO_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef UART_CONFIG_INFO_COLOR
|
||||
#define UART_CONFIG_INFO_COLOR 0
|
||||
#endif
|
||||
|
||||
// <o> UART_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef UART_CONFIG_DEBUG_COLOR
|
||||
#define UART_CONFIG_DEBUG_COLOR 0
|
||||
#endif
|
||||
|
||||
#endif //UART_CONFIG_LOG_ENABLED
|
||||
// </e>
|
||||
|
||||
#endif //UART_ENABLED
|
||||
// </e>
|
||||
|
||||
// </h>
|
||||
//==========================================================
|
||||
|
||||
// <h> nRF_Libraries
|
||||
|
||||
//==========================================================
|
||||
// <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
|
||||
//==========================================================
|
||||
#ifndef APP_TIMER_ENABLED
|
||||
#define APP_TIMER_ENABLED 1
|
||||
#endif
|
||||
#if APP_TIMER_ENABLED
|
||||
// <q> APP_TIMER_WITH_PROFILER - Enable app_timer profiling
|
||||
|
||||
|
||||
#ifndef APP_TIMER_WITH_PROFILER
|
||||
#define APP_TIMER_WITH_PROFILER 0
|
||||
#endif
|
||||
|
||||
// <q> APP_TIMER_KEEPS_RTC_ACTIVE - Enable RTC always on
|
||||
|
||||
|
||||
// <i> If option is enabled RTC is kept running even if there is no active timers.
|
||||
// <i> This option can be used when app_timer is used for timestamping.
|
||||
|
||||
#ifndef APP_TIMER_KEEPS_RTC_ACTIVE
|
||||
#define APP_TIMER_KEEPS_RTC_ACTIVE 0
|
||||
#endif
|
||||
|
||||
#endif //APP_TIMER_ENABLED
|
||||
// </e>
|
||||
|
||||
// <q> BUTTON_ENABLED - app_button - buttons handling module
|
||||
|
||||
|
||||
#ifndef BUTTON_ENABLED
|
||||
#define BUTTON_ENABLED 1
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
//==========================================================
|
||||
|
||||
// <h> nRF_Log
|
||||
|
||||
//==========================================================
|
||||
// <e> NRF_LOG_ENABLED - nrf_log - Logging
|
||||
//==========================================================
|
||||
#ifndef NRF_LOG_ENABLED
|
||||
#define NRF_LOG_ENABLED 0
|
||||
#endif
|
||||
#if NRF_LOG_ENABLED
|
||||
// <e> NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string
|
||||
//==========================================================
|
||||
#ifndef NRF_LOG_USES_COLORS
|
||||
#define NRF_LOG_USES_COLORS 0
|
||||
#endif
|
||||
#if NRF_LOG_USES_COLORS
|
||||
// <o> NRF_LOG_COLOR_DEFAULT - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef NRF_LOG_COLOR_DEFAULT
|
||||
#define NRF_LOG_COLOR_DEFAULT 0
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_ERROR_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef NRF_LOG_ERROR_COLOR
|
||||
#define NRF_LOG_ERROR_COLOR 0
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_WARNING_COLOR - ANSI escape code prefix.
|
||||
|
||||
// <0=> Default
|
||||
// <1=> Black
|
||||
// <2=> Red
|
||||
// <3=> Green
|
||||
// <4=> Yellow
|
||||
// <5=> Blue
|
||||
// <6=> Magenta
|
||||
// <7=> Cyan
|
||||
// <8=> White
|
||||
|
||||
#ifndef NRF_LOG_WARNING_COLOR
|
||||
#define NRF_LOG_WARNING_COLOR 0
|
||||
#endif
|
||||
|
||||
#endif //NRF_LOG_USES_COLORS
|
||||
// </e>
|
||||
|
||||
// <o> NRF_LOG_DEFAULT_LEVEL - Default Severity level
|
||||
|
||||
// <0=> Off
|
||||
// <1=> Error
|
||||
// <2=> Warning
|
||||
// <3=> Info
|
||||
// <4=> Debug
|
||||
|
||||
#ifndef NRF_LOG_DEFAULT_LEVEL
|
||||
#define NRF_LOG_DEFAULT_LEVEL 3
|
||||
#endif
|
||||
|
||||
// <e> NRF_LOG_DEFERRED - Enable deffered logger.
|
||||
|
||||
// <i> Log data is buffered and can be processed in idle.
|
||||
//==========================================================
|
||||
#ifndef NRF_LOG_DEFERRED
|
||||
#define NRF_LOG_DEFERRED 1
|
||||
#endif
|
||||
#if NRF_LOG_DEFERRED
|
||||
// <o> NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words.
|
||||
// <i> Must be power of 2
|
||||
|
||||
#ifndef NRF_LOG_DEFERRED_BUFSIZE
|
||||
#define NRF_LOG_DEFERRED_BUFSIZE 256
|
||||
#endif
|
||||
|
||||
#endif //NRF_LOG_DEFERRED
|
||||
// </e>
|
||||
|
||||
// <q> NRF_LOG_USES_TIMESTAMP - Enable timestamping
|
||||
|
||||
|
||||
// <i> Function for getting the timestamp is provided by the user
|
||||
|
||||
#ifndef NRF_LOG_USES_TIMESTAMP
|
||||
#define NRF_LOG_USES_TIMESTAMP 0
|
||||
#endif
|
||||
|
||||
#endif //NRF_LOG_ENABLED
|
||||
// </e>
|
||||
|
||||
// <h> nrf_log_backend - Logging sink
|
||||
|
||||
//==========================================================
|
||||
// <o> NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string
|
||||
// <i> Logger backend RAM usage is determined by this value.
|
||||
|
||||
#ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH
|
||||
#define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp
|
||||
// <i> If higher resolution timestamp source is used it might be needed to increase that
|
||||
|
||||
#ifndef NRF_LOG_TIMESTAMP_DIGITS
|
||||
#define NRF_LOG_TIMESTAMP_DIGITS 8
|
||||
#endif
|
||||
|
||||
// <e> NRF_LOG_BACKEND_SERIAL_USES_UART - If enabled data is printed over UART
|
||||
//==========================================================
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_USES_UART
|
||||
#define NRF_LOG_BACKEND_SERIAL_USES_UART 1
|
||||
#endif
|
||||
#if NRF_LOG_BACKEND_SERIAL_USES_UART
|
||||
// <o> NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE - Default Baudrate
|
||||
|
||||
// <323584=> 1200 baud
|
||||
// <643072=> 2400 baud
|
||||
// <1290240=> 4800 baud
|
||||
// <2576384=> 9600 baud
|
||||
// <3862528=> 14400 baud
|
||||
// <5152768=> 19200 baud
|
||||
// <7716864=> 28800 baud
|
||||
// <10289152=> 38400 baud
|
||||
// <15400960=> 57600 baud
|
||||
// <20615168=> 76800 baud
|
||||
// <30801920=> 115200 baud
|
||||
// <61865984=> 230400 baud
|
||||
// <67108864=> 250000 baud
|
||||
// <121634816=> 460800 baud
|
||||
// <251658240=> 921600 baud
|
||||
// <268435456=> 57600 baud
|
||||
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE
|
||||
#define NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 30801920
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_BACKEND_SERIAL_UART_TX_PIN - UART TX pin
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_UART_TX_PIN
|
||||
#define NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 6
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_BACKEND_SERIAL_UART_RX_PIN - UART RX pin
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_UART_RX_PIN
|
||||
#define NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 8
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN - UART RTS pin
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN
|
||||
#define NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 5
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN - UART CTS pin
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN
|
||||
#define NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 7
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL - Hardware Flow Control
|
||||
|
||||
// <0=> Disabled
|
||||
// <1=> Enabled
|
||||
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL
|
||||
#define NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 0
|
||||
#endif
|
||||
|
||||
// <o> NRF_LOG_BACKEND_UART_INSTANCE - UART instance used
|
||||
|
||||
// <0=> 0
|
||||
|
||||
#ifndef NRF_LOG_BACKEND_UART_INSTANCE
|
||||
#define NRF_LOG_BACKEND_UART_INSTANCE 0
|
||||
#endif
|
||||
|
||||
#endif //NRF_LOG_BACKEND_SERIAL_USES_UART
|
||||
// </e>
|
||||
|
||||
// <e> NRF_LOG_BACKEND_SERIAL_USES_RTT - If enabled data is printed using RTT
|
||||
//==========================================================
|
||||
#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT
|
||||
#define NRF_LOG_BACKEND_SERIAL_USES_RTT 0
|
||||
#endif
|
||||
#if NRF_LOG_BACKEND_SERIAL_USES_RTT
|
||||
// <o> NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE - RTT output buffer size.
|
||||
// <i> Should be equal or bigger than \ref NRF_LOG_BACKEND_MAX_STRING_LENGTH.
|
||||
// <i> This value is used in Segger RTT configuration to set the buffer size
|
||||
// <i> if it is bigger than default RTT buffer size.
|
||||
|
||||
#ifndef NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE
|
||||
#define NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 512
|
||||
#endif
|
||||
|
||||
#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT
|
||||
// </e>
|
||||
|
||||
// </h>
|
||||
//==========================================================
|
||||
|
||||
// </h>
|
||||
//==========================================================
|
||||
|
||||
// <h> nRF_Segger_RTT
|
||||
|
||||
//==========================================================
|
||||
// <h> segger_rtt - SEGGER RTT
|
||||
|
||||
//==========================================================
|
||||
// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer.
|
||||
#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
|
||||
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 64
|
||||
#endif
|
||||
|
||||
// <o> SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer.
|
||||
#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
|
||||
#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
|
||||
#endif
|
||||
|
||||
// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer.
|
||||
#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
|
||||
#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
|
||||
#endif
|
||||
|
||||
// <o> SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer.
|
||||
#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
|
||||
#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
|
||||
#endif
|
||||
|
||||
// </h>
|
||||
//==========================================================
|
||||
|
||||
// </h>
|
||||
//==========================================================
|
||||
|
||||
// <<< end of configuration section >>>
|
||||
#endif //SDK_CONFIG_H
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
/* mbed Microcontroller Library - cmsis_nvic
|
||||
* Copyright (c) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*/
|
||||
|
||||
#ifndef MBED_CMSIS_NVIC_H
|
||||
#define MBED_CMSIS_NVIC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define NVIC_NUM_VECTORS (16 + 38) // CORE + MCU Peripherals
|
||||
#define NVIC_USER_IRQ_OFFSET 16
|
||||
|
||||
#include "nrf52.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void NVIC_Relocate(void);
|
||||
void NVIC_SetVector(IRQn_Type IRQn, uint32_t vector);
|
||||
uint32_t NVIC_GetVector(IRQn_Type IRQn);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef H_NRF52_HAL_
|
||||
#define H_NRF52_HAL_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Helper functions to enable/disable interrupts. */
|
||||
#define __HAL_DISABLE_INTERRUPTS(x) \
|
||||
do { \
|
||||
x = __get_PRIMASK(); \
|
||||
__disable_irq(); \
|
||||
} while(0);
|
||||
|
||||
#define __HAL_ENABLE_INTERRUPTS(x) \
|
||||
do { \
|
||||
if (!x) { \
|
||||
__enable_irq(); \
|
||||
} \
|
||||
} while(0);
|
||||
|
||||
struct nrf52_uart_cfg {
|
||||
int8_t suc_pin_tx; /* pins for IO */
|
||||
int8_t suc_pin_rx;
|
||||
int8_t suc_pin_rts;
|
||||
int8_t suc_pin_cts;
|
||||
};
|
||||
const struct nrf52_uart_cfg *bsp_uart_config(void);
|
||||
|
||||
struct nrf52_hal_i2c_cfg {
|
||||
int scl_pin;
|
||||
int sda_pin;
|
||||
uint32_t i2c_frequency;
|
||||
};
|
||||
struct hal_flash;
|
||||
extern const struct hal_flash nrf52k_flash_dev;
|
||||
|
||||
/* SPI configuration (used for both master and slave) */
|
||||
struct nrf52_hal_spi_cfg {
|
||||
uint8_t sck_pin;
|
||||
uint8_t mosi_pin;
|
||||
uint8_t miso_pin;
|
||||
uint8_t ss_pin;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* H_NRF52_HAL_ */
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
#ifndef _OS_ARCH_H
|
||||
#define _OS_ARCH_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "FreeRTOSConfig.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int os_sr_t;
|
||||
typedef int os_stack_t;
|
||||
|
||||
#define OS_ALIGNMENT (4)
|
||||
#define OS_TICKS_PER_SEC (configTICK_RATE_HZ)
|
||||
|
||||
#define OS_ENTER_CRITICAL(unused) do { (void)unused; vPortEnterCritical(); } while (0)
|
||||
#define OS_EXIT_CRITICAL(unused) do { (void)unused; vPortExitCritical(); } while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_ARCH_H */
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _OS_CALLOUT_H
|
||||
#define _OS_CALLOUT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "os/os_eventq.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "timers.h"
|
||||
|
||||
struct os_callout {
|
||||
struct os_event c_ev;
|
||||
struct os_eventq *c_evq;
|
||||
uint32_t c_ticks;
|
||||
TimerHandle_t c_timer;
|
||||
};
|
||||
|
||||
void os_callout_init(struct os_callout *cf, struct os_eventq *evq,
|
||||
os_event_fn *ev_cb, void *ev_arg);
|
||||
int os_callout_reset(struct os_callout *, int32_t);
|
||||
int os_callout_queued(struct os_callout *c);
|
||||
void os_callout_stop(struct os_callout *c);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_CALLOUT_H */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_EVENTQ_H
|
||||
#define _OS_EVENTQ_H
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "os/os_time.h"
|
||||
#include "os/queue.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_event;
|
||||
typedef void os_event_fn(struct os_event *ev);
|
||||
|
||||
struct os_event {
|
||||
uint8_t ev_queued;
|
||||
os_event_fn *ev_cb;
|
||||
void *ev_arg;
|
||||
};
|
||||
|
||||
#define OS_EVENT_QUEUED(__ev) ((__ev)->ev_queued)
|
||||
|
||||
struct os_eventq {
|
||||
QueueHandle_t q;
|
||||
};
|
||||
|
||||
void os_eventq_init(struct os_eventq *);
|
||||
int os_eventq_inited(const struct os_eventq *evq);
|
||||
void os_eventq_put(struct os_eventq *, struct os_event *);
|
||||
struct os_event *os_eventq_get_no_wait(struct os_eventq *evq);
|
||||
struct os_event *os_eventq_get(struct os_eventq *);
|
||||
void os_eventq_run(struct os_eventq *evq);
|
||||
struct os_event *os_eventq_poll(struct os_eventq **, int, os_time_t);
|
||||
void os_eventq_remove(struct os_eventq *, struct os_event *);
|
||||
struct os_eventq *os_eventq_dflt_get(void);
|
||||
|
||||
/* [DEPRECATED] */
|
||||
void os_eventq_designate(struct os_eventq **dst, struct os_eventq *val,
|
||||
struct os_event *start_ev);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_EVENTQ_H */
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _OS_MUTEX_H_
|
||||
#define _OS_MUTEX_H_
|
||||
|
||||
#include "os/os.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct os_mutex
|
||||
{
|
||||
SemaphoreHandle_t handle;
|
||||
};
|
||||
|
||||
os_error_t os_mutex_init(struct os_mutex *mu);
|
||||
|
||||
os_error_t os_mutex_release(struct os_mutex *mu);
|
||||
|
||||
os_error_t os_mutex_pend(struct os_mutex *mu, uint32_t timeout);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_MUTEX_H_ */
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef _OS_SEM_H_
|
||||
#define _OS_SEM_H_
|
||||
|
||||
#include "os/os_error.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
|
||||
struct os_sem
|
||||
{
|
||||
SemaphoreHandle_t handle;
|
||||
};
|
||||
|
||||
os_error_t os_sem_init(struct os_sem *sem, uint16_t tokens);
|
||||
os_error_t os_sem_release(struct os_sem *sem);
|
||||
os_error_t os_sem_pend(struct os_sem *sem, uint32_t timeout);
|
||||
uint16_t os_sem_get_count(struct os_sem *sem);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _OS_SEM_H_ */
|
||||
@@ -0,0 +1,967 @@
|
||||
/**
|
||||
* This file was generated by Apache Newt version: 1.2.0-dev
|
||||
*/
|
||||
|
||||
#ifndef H_MYNEWT_SYSCFG_
|
||||
#define H_MYNEWT_SYSCFG_
|
||||
|
||||
/**
|
||||
* This macro exists to ensure code includes this header when needed. If code
|
||||
* checks the existence of a setting directly via ifdef without including this
|
||||
* header, the setting macro will silently evaluate to 0. In contrast, an
|
||||
* attempt to use these macros without including this header will result in a
|
||||
* compiler error.
|
||||
*/
|
||||
#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x
|
||||
|
||||
|
||||
|
||||
/*** compiler/arm-none-eabi-m4 */
|
||||
#ifndef MYNEWT_VAL_HARDFLOAT
|
||||
#define MYNEWT_VAL_HARDFLOAT (0)
|
||||
#endif
|
||||
|
||||
/*** hw/bsp/nrf52840pdk */
|
||||
#ifndef MYNEWT_VAL_BSP_NRF52840
|
||||
#define MYNEWT_VAL_BSP_NRF52840 (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_TIMER_0
|
||||
#define MYNEWT_VAL_TIMER_0 (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_TIMER_1
|
||||
#define MYNEWT_VAL_TIMER_1 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_TIMER_2
|
||||
#define MYNEWT_VAL_TIMER_2 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_TIMER_3
|
||||
#define MYNEWT_VAL_TIMER_3 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_TIMER_4
|
||||
#define MYNEWT_VAL_TIMER_4 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_TIMER_5
|
||||
#define MYNEWT_VAL_TIMER_5 (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_0
|
||||
#define MYNEWT_VAL_UART_0 (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_0_PIN_CTS
|
||||
#define MYNEWT_VAL_UART_0_PIN_CTS (7)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_0_PIN_RTS
|
||||
#define MYNEWT_VAL_UART_0_PIN_RTS (5)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_0_PIN_RX
|
||||
#define MYNEWT_VAL_UART_0_PIN_RX (8)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_0_PIN_TX
|
||||
#define MYNEWT_VAL_UART_0_PIN_TX (6)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_1
|
||||
#define MYNEWT_VAL_UART_1 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_1_PIN_RX
|
||||
#define MYNEWT_VAL_UART_1_PIN_RX (-1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_UART_1_PIN_TX
|
||||
#define MYNEWT_VAL_UART_1_PIN_TX (-1)
|
||||
#endif
|
||||
|
||||
/*** hw/drivers/nimble/nrf52 */
|
||||
#ifndef MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN
|
||||
#define MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN
|
||||
#define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN
|
||||
#define MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN (-1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN
|
||||
#define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1)
|
||||
#endif
|
||||
|
||||
/*** hw/mcu/nordic/nrf52xxx */
|
||||
#ifndef MYNEWT_VAL_I2C_0
|
||||
#define MYNEWT_VAL_I2C_0 (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_I2C_1
|
||||
#define MYNEWT_VAL_I2C_1 (0)
|
||||
#endif
|
||||
|
||||
/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */
|
||||
#ifndef MYNEWT_VAL_MCU_DCDC_ENABLED
|
||||
#define MYNEWT_VAL_MCU_DCDC_ENABLED (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE
|
||||
#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SPI_0_MASTER
|
||||
#define MYNEWT_VAL_SPI_0_MASTER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SPI_0_SLAVE
|
||||
#define MYNEWT_VAL_SPI_0_SLAVE (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SPI_1_MASTER
|
||||
#define MYNEWT_VAL_SPI_1_MASTER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SPI_1_SLAVE
|
||||
#define MYNEWT_VAL_SPI_1_SLAVE (0)
|
||||
#endif
|
||||
|
||||
/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */
|
||||
#ifndef MYNEWT_VAL_XTAL_32768
|
||||
#define MYNEWT_VAL_XTAL_32768 (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_XTAL_32768_SYNTH
|
||||
#define MYNEWT_VAL_XTAL_32768_SYNTH (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_XTAL_RC
|
||||
#define MYNEWT_VAL_XTAL_RC (0)
|
||||
#endif
|
||||
|
||||
/*** kernel/os */
|
||||
#ifndef MYNEWT_VAL_FLOAT_USER
|
||||
#define MYNEWT_VAL_FLOAT_USER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT
|
||||
#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (12)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE
|
||||
#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT
|
||||
#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_MSYS_2_BLOCK_SIZE
|
||||
#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_CLI
|
||||
#define MYNEWT_VAL_OS_CLI (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_COREDUMP
|
||||
#define MYNEWT_VAL_OS_COREDUMP (0)
|
||||
#endif
|
||||
|
||||
/* Overridden by hw/bsp/nrf52840pdk (defined by kernel/os) */
|
||||
#ifndef MYNEWT_VAL_OS_CPUTIME_FREQ
|
||||
#define MYNEWT_VAL_OS_CPUTIME_FREQ (32768)
|
||||
#endif
|
||||
|
||||
/* Overridden by hw/bsp/nrf52840pdk (defined by kernel/os) */
|
||||
#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM
|
||||
#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (5)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_CHECK
|
||||
#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_GUARD
|
||||
#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE
|
||||
#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_MAIN_TASK_PRIO
|
||||
#define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_MEMPOOL_CHECK
|
||||
#define MYNEWT_VAL_OS_MEMPOOL_CHECK (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_MEMPOOL_POISON
|
||||
#define MYNEWT_VAL_OS_MEMPOOL_POISON (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_SCHEDULING
|
||||
#define MYNEWT_VAL_OS_SCHEDULING (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_OS_SYSVIEW
|
||||
#define MYNEWT_VAL_OS_SYSVIEW (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SANITY_INTERVAL
|
||||
#define MYNEWT_VAL_SANITY_INTERVAL (15000)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_WATCHDOG_INTERVAL
|
||||
#define MYNEWT_VAL_WATCHDOG_INTERVAL (30000)
|
||||
#endif
|
||||
|
||||
/*** libc/baselibc */
|
||||
#ifndef MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE
|
||||
#define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BASELIBC_PRESENT
|
||||
#define MYNEWT_VAL_BASELIBC_PRESENT (1)
|
||||
#endif
|
||||
|
||||
/*** net/nimble */
|
||||
#ifndef MYNEWT_VAL_BLE_EXT_ADV
|
||||
#define MYNEWT_VAL_BLE_EXT_ADV (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE
|
||||
#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS
|
||||
#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
|
||||
#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
|
||||
#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL
|
||||
#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER
|
||||
#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL
|
||||
#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_WHITELIST
|
||||
#define MYNEWT_VAL_BLE_WHITELIST (1)
|
||||
#endif
|
||||
|
||||
/*** net/nimble/controller */
|
||||
#ifndef MYNEWT_VAL_BLE_DEVICE
|
||||
#define MYNEWT_VAL_BLE_DEVICE (1)
|
||||
#endif
|
||||
|
||||
/* Overridden by net/nimble/controller (defined by net/nimble/controller) */
|
||||
#ifndef MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE
|
||||
#define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS
|
||||
#define MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_EXT_SCAN_FILT
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_EXT_SCAN_FILT (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0)
|
||||
#endif
|
||||
|
||||
/* Overridden by net/nimble/controller (defined by net/nimble/controller) */
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (MYNEWT_VAL_BLE_EXT_ADV)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
|
||||
#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES
|
||||
#define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (27)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET
|
||||
#define MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS
|
||||
#define MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS (4)
|
||||
#endif
|
||||
|
||||
/* Overridden by net/nimble/controller (defined by net/nimble/controller) */
|
||||
#ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT
|
||||
#define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (5)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA
|
||||
#define MYNEWT_VAL_BLE_LL_MASTER_SCA (4)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE
|
||||
#define MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE (251)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_MFRG_ID
|
||||
#define MYNEWT_VAL_BLE_LL_MFRG_ID (0xFFFF)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS
|
||||
#define MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS (8)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS
|
||||
#define MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS (8)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_OUR_SCA
|
||||
#define MYNEWT_VAL_BLE_LL_OUR_SCA (60)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_PRIO
|
||||
#define MYNEWT_VAL_BLE_LL_PRIO (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE
|
||||
#define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_RNG_BUFSIZE
|
||||
#define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING
|
||||
#define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES
|
||||
#define MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES
|
||||
#define MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_TX_PWR_DBM
|
||||
#define MYNEWT_VAL_BLE_LL_TX_PWR_DBM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD
|
||||
#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (3250)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LL_WHITELIST_SIZE
|
||||
#define MYNEWT_VAL_BLE_LL_WHITELIST_SIZE (8)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_LP_CLOCK
|
||||
#define MYNEWT_VAL_BLE_LP_CLOCK (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE
|
||||
#define MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE (((2000 * OS_TICKS_PER_SEC) / 1000))
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR
|
||||
#define MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR ((uint8_t[6]){0xff, 0xaa, 0xff, 0xc0, 0xde, 0xc0})
|
||||
#endif
|
||||
|
||||
/* Overridden by hw/bsp/nrf52840pdk (defined by net/nimble/controller) */
|
||||
#ifndef MYNEWT_VAL_BLE_XTAL_SETTLE_TIME
|
||||
#define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (1500)
|
||||
#endif
|
||||
|
||||
/*** net/nimble/host */
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU
|
||||
#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_INDICATE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_READ (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP
|
||||
#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS
|
||||
#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS
|
||||
#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS
|
||||
#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID
|
||||
#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID
|
||||
#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS
|
||||
#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_INDICATE
|
||||
#define MYNEWT_VAL_BLE_GATT_INDICATE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_MAX_PROCS
|
||||
#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY
|
||||
#define MYNEWT_VAL_BLE_GATT_NOTIFY (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_READ
|
||||
#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_READ_LONG
|
||||
#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS
|
||||
#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT
|
||||
#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_READ_UUID
|
||||
#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_RESUME_RATE
|
||||
#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_SIGNED_WRITE
|
||||
#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_WRITE
|
||||
#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_WRITE_LONG
|
||||
#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS
|
||||
#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP
|
||||
#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE
|
||||
#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HOST
|
||||
#define MYNEWT_VAL_BLE_HOST (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HS_DEBUG
|
||||
#define MYNEWT_VAL_BLE_HS_DEBUG (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS
|
||||
#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HS_REQUIRE_OS
|
||||
#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM
|
||||
#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS
|
||||
#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_L2CAP_MAX_CHANS
|
||||
#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT
|
||||
#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS
|
||||
#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1)
|
||||
#endif
|
||||
|
||||
/* Overridden by apps/bleall (defined by net/nimble/host) */
|
||||
#ifndef MYNEWT_VAL_BLE_MESH
|
||||
#define MYNEWT_VAL_BLE_MESH (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE
|
||||
#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT
|
||||
#define MYNEWT_VAL_BLE_MONITOR_RTT (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED
|
||||
#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME
|
||||
#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("monitor")
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE
|
||||
#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_UART
|
||||
#define MYNEWT_VAL_BLE_MONITOR_UART (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE
|
||||
#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE
|
||||
#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV
|
||||
#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0")
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT
|
||||
#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_BONDING
|
||||
#define MYNEWT_VAL_BLE_SM_BONDING (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_IO_CAP
|
||||
#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_KEYPRESS
|
||||
#define MYNEWT_VAL_BLE_SM_KEYPRESS (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_LEGACY
|
||||
#define MYNEWT_VAL_BLE_SM_LEGACY (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS
|
||||
#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_MITM
|
||||
#define MYNEWT_VAL_BLE_SM_MITM (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG
|
||||
#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST
|
||||
#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0)
|
||||
#endif
|
||||
|
||||
/* Overridden by net/nimble/host (defined by net/nimble/host) */
|
||||
#ifndef MYNEWT_VAL_BLE_SM_SC
|
||||
#define MYNEWT_VAL_BLE_SM_SC (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST
|
||||
#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS
|
||||
#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS
|
||||
#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8)
|
||||
#endif
|
||||
|
||||
/*** net/nimble/host/mesh */
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (10)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO
|
||||
#define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_CRPL
|
||||
#define MYNEWT_VAL_BLE_MESH_CRPL (10)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ADV
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_ADV (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_BEACON
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_BEACON (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CRYPTO
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_CRYPTO (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_FRIEND
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_FRIEND (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_LOW_POWER
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_LOW_POWER (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_MODEL
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_MODEL (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_NET
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_NET (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_PROV
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_PROV (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_PROXY
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_PROXY (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_TRANS
|
||||
#define MYNEWT_VAL_BLE_MESH_DEBUG_TRANS (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_DEV_UUID
|
||||
#define MYNEWT_VAL_BLE_MESH_DEV_UUID (((uint8_t[16]){0x11, 0x22, 0}))
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_FRIEND
|
||||
#define MYNEWT_VAL_BLE_MESH_FRIEND (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE
|
||||
#define MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE (16)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN
|
||||
#define MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN (255)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE
|
||||
#define MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE (16)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY
|
||||
#define MYNEWT_VAL_BLE_MESH_GATT_PROXY (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST
|
||||
#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LABEL_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_LABEL_COUNT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER
|
||||
#define MYNEWT_VAL_BLE_MESH_LOW_POWER (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_GROUPS
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_GROUPS (10)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT (100)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY (20)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY
|
||||
#define MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY (10)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE
|
||||
#define MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE (10)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV
|
||||
#define MYNEWT_VAL_BLE_MESH_PB_ADV (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_PB_GATT
|
||||
#define MYNEWT_VAL_BLE_MESH_PB_GATT (1)
|
||||
#endif
|
||||
|
||||
/* Overridden by net/nimble/host/mesh (defined by net/nimble/host/mesh) */
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_PROV
|
||||
#define MYNEWT_VAL_BLE_MESH_PROV (1)
|
||||
#endif
|
||||
|
||||
/* Overridden by net/nimble/host/mesh (defined by net/nimble/host/mesh) */
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_PROXY
|
||||
#define MYNEWT_VAL_BLE_MESH_PROXY (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE
|
||||
#define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_RELAY
|
||||
#define MYNEWT_VAL_BLE_MESH_RELAY (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_RX_SDU_MAX
|
||||
#define MYNEWT_VAL_BLE_MESH_RX_SDU_MAX (384)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (2)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_SUBNET_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_SUBNET_COUNT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT
|
||||
#define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (4)
|
||||
#endif
|
||||
|
||||
/*** net/nimble/host/services/ans */
|
||||
#ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT
|
||||
#define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT
|
||||
#define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0)
|
||||
#endif
|
||||
|
||||
/*** net/nimble/transport/ram */
|
||||
#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT
|
||||
#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (4)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE
|
||||
#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE
|
||||
#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT
|
||||
#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (2)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT
|
||||
#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8)
|
||||
#endif
|
||||
|
||||
/*** sys/console/stub */
|
||||
#ifndef MYNEWT_VAL_CONSOLE_UART_BAUD
|
||||
#define MYNEWT_VAL_CONSOLE_UART_BAUD (115200)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_CONSOLE_UART_DEV
|
||||
#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0")
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL
|
||||
#define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE)
|
||||
#endif
|
||||
|
||||
/*** sys/flash_map */
|
||||
#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS
|
||||
#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10)
|
||||
#endif
|
||||
|
||||
/*** sys/log/stub */
|
||||
#ifndef MYNEWT_VAL_LOG_CONSOLE
|
||||
#define MYNEWT_VAL_LOG_CONSOLE (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_LOG_FCB
|
||||
#define MYNEWT_VAL_LOG_FCB (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_LOG_LEVEL
|
||||
#define MYNEWT_VAL_LOG_LEVEL (255)
|
||||
#endif
|
||||
|
||||
/*** sys/sysinit */
|
||||
#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT
|
||||
#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE
|
||||
#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0)
|
||||
#endif
|
||||
|
||||
#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE
|
||||
#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/* Linker script to configure memory regions. */
|
||||
|
||||
SEARCH_DIR(.)
|
||||
GROUP(-lgcc -lc -lnosys)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x80000
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x10000
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.vector_relocation :
|
||||
{
|
||||
. = ALIGN(256);
|
||||
__vector_tbl_reloc__ = .;
|
||||
. = . + (__isr_vector_end - __isr_vector_start);
|
||||
. = ALIGN(256);
|
||||
} > RAM
|
||||
.fs_data :
|
||||
{
|
||||
PROVIDE(__start_fs_data = .);
|
||||
KEEP(*(.fs_data))
|
||||
PROVIDE(__stop_fs_data = .);
|
||||
} > RAM
|
||||
.pwr_mgmt_data :
|
||||
{
|
||||
PROVIDE(__start_pwr_mgmt_data = .);
|
||||
KEEP(*(.pwr_mgmt_data))
|
||||
PROVIDE(__stop_pwr_mgmt_data = .);
|
||||
} > RAM
|
||||
} INSERT AFTER .data;
|
||||
|
||||
INCLUDE "nrf5x_common.ld"
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "bsp.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
#include "nimble_port.h"
|
||||
#include "host/ble_hs.h"
|
||||
#include "services/gap/ble_svc_gap.h"
|
||||
#include "services/ias/ble_svc_ias.h"
|
||||
|
||||
#if LEDS_NUMBER < 4
|
||||
#error "Board is not equipped with enough amount of LEDs"
|
||||
#endif
|
||||
|
||||
static const char gap_name[] = "freertos";
|
||||
|
||||
static TaskHandle_t task_h;
|
||||
static TimerHandle_t led_tmr_h;
|
||||
|
||||
static void start_advertise(void);
|
||||
|
||||
static int
|
||||
ias_event_cb(uint8_t alert_level)
|
||||
{
|
||||
switch (alert_level) {
|
||||
case BLE_SVC_IAS_ALERT_LEVEL_NO_ALERT:
|
||||
xTimerStop(led_tmr_h, portMAX_DELAY);
|
||||
bsp_board_leds_off();
|
||||
break;
|
||||
case BLE_SVC_IAS_ALERT_LEVEL_MILD_ALERT:
|
||||
bsp_board_led_on(BSP_BOARD_LED_0);
|
||||
bsp_board_led_off(BSP_BOARD_LED_1);
|
||||
bsp_board_led_off(BSP_BOARD_LED_2);
|
||||
bsp_board_led_on(BSP_BOARD_LED_3);
|
||||
xTimerStart(led_tmr_h, portMAX_DELAY);
|
||||
break;
|
||||
case BLE_SVC_IAS_ALERT_LEVEL_HIGH_ALERT:
|
||||
bsp_board_leds_on();
|
||||
xTimerStart(led_tmr_h, portMAX_DELAY);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
put_ad(uint8_t ad_type, uint8_t ad_len, const void *ad, uint8_t *buf,
|
||||
uint8_t *len)
|
||||
{
|
||||
buf[(*len)++] = ad_len + 1;
|
||||
buf[(*len)++] = ad_type;
|
||||
|
||||
memcpy(&buf[*len], ad, ad_len);
|
||||
|
||||
*len += ad_len;
|
||||
}
|
||||
|
||||
static void
|
||||
update_ad(void)
|
||||
{
|
||||
uint8_t ad[BLE_HS_ADV_MAX_SZ];
|
||||
uint8_t ad_len = 0;
|
||||
uint8_t ad_flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
|
||||
uint16_t ad_uuid = htole16(BLE_SVC_IAS_UUID16);
|
||||
|
||||
put_ad(BLE_HS_ADV_TYPE_FLAGS, 1, &ad_flags, ad, &ad_len);
|
||||
put_ad(BLE_HS_ADV_TYPE_COMP_NAME, sizeof(gap_name), gap_name, ad, &ad_len);
|
||||
put_ad(BLE_HS_ADV_TYPE_COMP_UUIDS16, sizeof(ad_uuid), &ad_uuid, ad, &ad_len);
|
||||
|
||||
ble_gap_adv_set_data(ad, ad_len);
|
||||
}
|
||||
|
||||
static int
|
||||
gap_event_cb(struct ble_gap_event *event, void *arg)
|
||||
{
|
||||
switch (event->type) {
|
||||
case BLE_GAP_EVENT_CONNECT:
|
||||
if (event->connect.status) {
|
||||
start_advertise();
|
||||
}
|
||||
break;
|
||||
|
||||
case BLE_GAP_EVENT_DISCONNECT:
|
||||
start_advertise();
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
start_advertise(void)
|
||||
{
|
||||
struct ble_gap_adv_params advp;
|
||||
int rc;
|
||||
|
||||
update_ad();
|
||||
|
||||
memset(&advp, 0, sizeof advp);
|
||||
advp.conn_mode = BLE_GAP_CONN_MODE_UND;
|
||||
advp.disc_mode = BLE_GAP_DISC_MODE_GEN;
|
||||
rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
|
||||
&advp, gap_event_cb, NULL);
|
||||
assert(rc == 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_sync_cb(void)
|
||||
{
|
||||
start_advertise();
|
||||
}
|
||||
|
||||
static void
|
||||
task_func(void *param)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = hal_timer_init(0, NULL);
|
||||
assert(rc == 0);
|
||||
rc = hal_timer_init(5, NULL);
|
||||
assert(rc == 0);
|
||||
rc = os_cputime_init(MYNEWT_VAL(OS_CPUTIME_FREQ));
|
||||
assert(rc == 0);
|
||||
|
||||
nimble_init();
|
||||
|
||||
ble_hs_cfg.sync_cb = on_sync_cb;
|
||||
|
||||
ble_svc_gap_device_name_set(gap_name);
|
||||
ble_svc_ias_set_cb(ias_event_cb);
|
||||
|
||||
nimble_run();
|
||||
}
|
||||
|
||||
static void led_tmr_func(void *param)
|
||||
{
|
||||
bsp_board_led_invert(BSP_BOARD_LED_0);
|
||||
bsp_board_led_invert(BSP_BOARD_LED_1);
|
||||
bsp_board_led_invert(BSP_BOARD_LED_2);
|
||||
bsp_board_led_invert(BSP_BOARD_LED_3);
|
||||
}
|
||||
|
||||
void start_nimble(void)
|
||||
{
|
||||
void ble_ll_task(void *arg);
|
||||
|
||||
led_tmr_h = xTimerCreate("led", 500, pdTRUE, NULL, led_tmr_func);
|
||||
|
||||
xTaskCreate(task_func, "nimble", configMINIMAL_STACK_SIZE + 400,
|
||||
NULL, 2, &task_h);
|
||||
|
||||
xTaskCreate(ble_ll_task, "ll", configMINIMAL_STACK_SIZE + 100,
|
||||
NULL, 0, &task_h);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/* mbed Microcontroller Library - cmsis_nvic for XXXX
|
||||
* Copyright (c) 2009-2011 ARM Limited. All rights reserved.
|
||||
*
|
||||
* CMSIS-style functionality to support dynamic vectors
|
||||
*/
|
||||
#include "bsp/cmsis_nvic.h"
|
||||
|
||||
#ifndef __CORTEX_M
|
||||
#error "Macro __CORTEX_M not defined; must define cortex-m type!"
|
||||
#endif
|
||||
|
||||
#if (__CORTEX_M == 0)
|
||||
#ifndef __VTOR_PRESENT
|
||||
/* no VTOR is defined so we assume we can't relocate the vector table */
|
||||
#define __VTOR_PRESENT (0)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern char __isr_vector[];
|
||||
extern char __vector_tbl_reloc__[];
|
||||
|
||||
void
|
||||
NVIC_Relocate(void)
|
||||
{
|
||||
uint32_t *current_location;
|
||||
uint32_t *new_location;
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Relocate the vector table from its current position to the position
|
||||
* designated in the linker script.
|
||||
*/
|
||||
current_location = (uint32_t *)&__isr_vector;
|
||||
new_location = (uint32_t *)&__vector_tbl_reloc__;
|
||||
|
||||
if (new_location != current_location) {
|
||||
for (i = 0; i < NVIC_NUM_VECTORS; i++) {
|
||||
new_location[i] = current_location[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set VTOR except for M0 */
|
||||
#if ((__CORTEX_M == 0) && (__VTOR_PRESENT == 0))
|
||||
#else
|
||||
SCB->VTOR = (uint32_t)&__vector_tbl_reloc__;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
NVIC_SetVector(IRQn_Type IRQn, uint32_t vector)
|
||||
{
|
||||
uint32_t *vectors;
|
||||
#if ((__CORTEX_M == 0) && (__VTOR_PRESENT == 0))
|
||||
vectors = (uint32_t *)&__vector_tbl_reloc__;
|
||||
#else
|
||||
vectors = (uint32_t *)SCB->VTOR;
|
||||
#endif
|
||||
vectors[IRQn + NVIC_USER_IRQ_OFFSET] = vector;
|
||||
__DMB();
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NVIC_GetVector(IRQn_Type IRQn)
|
||||
{
|
||||
uint32_t *vectors;
|
||||
#if (__CORTEX_M == 0)
|
||||
vectors = (uint32_t *)&__vector_tbl_reloc__;
|
||||
#else
|
||||
vectors = (uint32_t*)SCB->VTOR;
|
||||
#endif
|
||||
return vectors[IRQn + NVIC_USER_IRQ_OFFSET];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,932 @@
|
||||
/*
|
||||
* 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 <string.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include "syscfg/syscfg.h"
|
||||
#include "bsp/cmsis_nvic.h"
|
||||
#include "hal/hal_timer.h"
|
||||
#include "os/os_trace_api.h"
|
||||
#include "nrf.h"
|
||||
#include "mcu/nrf52_hal.h"
|
||||
|
||||
/* IRQ prototype */
|
||||
typedef void (*hal_timer_irq_handler_t)(void);
|
||||
|
||||
/* User CC 2 for reading counter, CC 3 for timer isr */
|
||||
#define NRF_TIMER_CC_READ (2)
|
||||
#define NRF_TIMER_CC_INT (3)
|
||||
|
||||
/* Output compare 2 used for RTC timers */
|
||||
#define NRF_RTC_TIMER_CC_INT (2)
|
||||
|
||||
/* Maximum number of hal timers used */
|
||||
#define NRF52_HAL_TIMER_MAX (6)
|
||||
|
||||
/* Maximum timer frequency */
|
||||
#define NRF52_MAX_TIMER_FREQ (16000000)
|
||||
|
||||
struct nrf52_hal_timer {
|
||||
uint8_t tmr_enabled;
|
||||
uint8_t tmr_irq_num;
|
||||
uint8_t tmr_rtc;
|
||||
uint8_t tmr_pad;
|
||||
uint32_t tmr_cntr;
|
||||
uint32_t timer_isrs;
|
||||
uint32_t tmr_freq;
|
||||
void *tmr_reg;
|
||||
TAILQ_HEAD(hal_timer_qhead, hal_timer) hal_timer_q;
|
||||
};
|
||||
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
struct nrf52_hal_timer nrf52_hal_timer0;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
struct nrf52_hal_timer nrf52_hal_timer1;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
struct nrf52_hal_timer nrf52_hal_timer2;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
struct nrf52_hal_timer nrf52_hal_timer3;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
struct nrf52_hal_timer nrf52_hal_timer4;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
struct nrf52_hal_timer nrf52_hal_timer5;
|
||||
#endif
|
||||
|
||||
static const struct nrf52_hal_timer *nrf52_hal_timers[NRF52_HAL_TIMER_MAX] = {
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
&nrf52_hal_timer0,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
&nrf52_hal_timer1,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
&nrf52_hal_timer2,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
&nrf52_hal_timer3,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
&nrf52_hal_timer4,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
&nrf52_hal_timer5
|
||||
#else
|
||||
NULL
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Resolve timer number into timer structure */
|
||||
#define NRF52_HAL_TIMER_RESOLVE(__n, __v) \
|
||||
if ((__n) >= NRF52_HAL_TIMER_MAX) { \
|
||||
rc = EINVAL; \
|
||||
goto err; \
|
||||
} \
|
||||
(__v) = (struct nrf52_hal_timer *) nrf52_hal_timers[(__n)]; \
|
||||
if ((__v) == NULL) { \
|
||||
rc = EINVAL; \
|
||||
goto err; \
|
||||
}
|
||||
|
||||
/* Interrupt mask for interrupt enable/clear */
|
||||
#define NRF_TIMER_INT_MASK(x) ((1 << (uint32_t)(x)) << 16)
|
||||
|
||||
static uint32_t
|
||||
nrf_read_timer_cntr(NRF_TIMER_Type *hwtimer)
|
||||
{
|
||||
uint32_t tcntr;
|
||||
|
||||
/* Force a capture of the timer into 'cntr' capture channel; read it */
|
||||
hwtimer->TASKS_CAPTURE[NRF_TIMER_CC_READ] = 1;
|
||||
tcntr = hwtimer->CC[NRF_TIMER_CC_READ];
|
||||
|
||||
return tcntr;
|
||||
}
|
||||
|
||||
/**
|
||||
* nrf timer set ocmp
|
||||
*
|
||||
* Set the OCMP used by the timer to the desired expiration tick
|
||||
*
|
||||
* NOTE: Must be called with interrupts disabled.
|
||||
*
|
||||
* @param timer Pointer to timer.
|
||||
*/
|
||||
static void
|
||||
nrf_timer_set_ocmp(struct nrf52_hal_timer *bsptimer, uint32_t expiry)
|
||||
{
|
||||
int32_t delta_t;
|
||||
uint32_t temp;
|
||||
uint32_t cntr;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
if (bsptimer->tmr_rtc) {
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT);
|
||||
temp = bsptimer->tmr_cntr;
|
||||
cntr = rtctimer->COUNTER;
|
||||
if (rtctimer->EVENTS_OVRFLW) {
|
||||
temp += (1UL << 24);
|
||||
cntr = rtctimer->COUNTER;
|
||||
}
|
||||
temp |= cntr;
|
||||
delta_t = (int32_t)(expiry - temp);
|
||||
|
||||
/*
|
||||
* The nrf documentation states that you must set the output
|
||||
* compare to 2 greater than the counter to guarantee an interrupt.
|
||||
* Since the counter can tick once while we check, we make sure
|
||||
* it is greater than 2.
|
||||
*/
|
||||
if (delta_t < 3) {
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
} else {
|
||||
if (delta_t < (1UL << 24)) {
|
||||
rtctimer->CC[NRF_RTC_TIMER_CC_INT] = expiry & 0x00ffffff;
|
||||
} else {
|
||||
/* CC too far ahead. Just make sure we set compare far ahead */
|
||||
rtctimer->CC[NRF_RTC_TIMER_CC_INT] = cntr + (1UL << 23);
|
||||
}
|
||||
rtctimer->INTENSET = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT);
|
||||
}
|
||||
} else {
|
||||
hwtimer = bsptimer->tmr_reg;
|
||||
|
||||
/* Disable ocmp interrupt and set new value */
|
||||
hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT);
|
||||
|
||||
/* Set output compare register to timer expiration */
|
||||
hwtimer->CC[NRF_TIMER_CC_INT] = expiry;
|
||||
|
||||
/* Clear interrupt flag */
|
||||
hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0;
|
||||
|
||||
/* Enable the output compare interrupt */
|
||||
hwtimer->INTENSET = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT);
|
||||
|
||||
/* Force interrupt to occur as we may have missed it */
|
||||
if ((int32_t)(nrf_read_timer_cntr(hwtimer) - expiry) >= 0) {
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable output compare used for timer */
|
||||
static void
|
||||
nrf_timer_disable_ocmp(NRF_TIMER_Type *hwtimer)
|
||||
{
|
||||
hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT);
|
||||
}
|
||||
|
||||
static void
|
||||
nrf_rtc_disable_ocmp(NRF_RTC_Type *rtctimer)
|
||||
{
|
||||
rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT);
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
hal_timer_read_bsptimer(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t low32;
|
||||
uint32_t ctx;
|
||||
uint32_t tcntr;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
tcntr = bsptimer->tmr_cntr;
|
||||
low32 = rtctimer->COUNTER;
|
||||
if (rtctimer->EVENTS_OVRFLW) {
|
||||
tcntr += (1UL << 24);
|
||||
bsptimer->tmr_cntr = tcntr;
|
||||
low32 = rtctimer->COUNTER;
|
||||
rtctimer->EVENTS_OVRFLW = 0;
|
||||
NVIC_SetPendingIRQ(bsptimer->tmr_irq_num);
|
||||
}
|
||||
tcntr |= low32;
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return tcntr;
|
||||
}
|
||||
|
||||
#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \
|
||||
MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4) || MYNEWT_VAL(TIMER_5))
|
||||
/**
|
||||
* hal timer chk queue
|
||||
*
|
||||
*
|
||||
* @param bsptimer
|
||||
*/
|
||||
static void
|
||||
hal_timer_chk_queue(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
int32_t delta;
|
||||
uint32_t tcntr;
|
||||
uint32_t ctx;
|
||||
struct hal_timer *timer;
|
||||
|
||||
/* disable interrupts */
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
while ((timer = TAILQ_FIRST(&bsptimer->hal_timer_q)) != NULL) {
|
||||
if (bsptimer->tmr_rtc) {
|
||||
tcntr = hal_timer_read_bsptimer(bsptimer);
|
||||
/*
|
||||
* If we are within 3 ticks of RTC, we wont be able to set compare.
|
||||
* Thus, we have to service this timer early.
|
||||
*/
|
||||
delta = -3;
|
||||
} else {
|
||||
tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg);
|
||||
delta = 0;
|
||||
}
|
||||
if ((int32_t)(tcntr - timer->expiry) >= delta) {
|
||||
TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link);
|
||||
timer->link.tqe_prev = NULL;
|
||||
timer->cb_func(timer->cb_arg);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Any timers left on queue? If so, we need to set OCMP */
|
||||
timer = TAILQ_FIRST(&bsptimer->hal_timer_q);
|
||||
if (timer) {
|
||||
nrf_timer_set_ocmp(bsptimer, timer->expiry);
|
||||
} else {
|
||||
if (bsptimer->tmr_rtc) {
|
||||
nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg);
|
||||
} else {
|
||||
nrf_timer_disable_ocmp(bsptimer->tmr_reg);
|
||||
}
|
||||
}
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal timer irq handler
|
||||
*
|
||||
* Generic HAL timer irq handler.
|
||||
*
|
||||
* @param tmr
|
||||
*/
|
||||
/**
|
||||
* hal timer irq handler
|
||||
*
|
||||
* This is the global timer interrupt routine.
|
||||
*
|
||||
*/
|
||||
#if (MYNEWT_VAL(TIMER_0) || MYNEWT_VAL(TIMER_1) || MYNEWT_VAL(TIMER_2) || \
|
||||
MYNEWT_VAL(TIMER_3) || MYNEWT_VAL(TIMER_4))
|
||||
|
||||
static void
|
||||
hal_timer_irq_handler(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t compare;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
|
||||
os_trace_enter_isr();
|
||||
|
||||
/* Check interrupt source. If set, clear them */
|
||||
hwtimer = bsptimer->tmr_reg;
|
||||
compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT];
|
||||
if (compare) {
|
||||
hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT] = 0;
|
||||
}
|
||||
|
||||
/* XXX: make these stats? */
|
||||
/* Count # of timer isrs */
|
||||
++bsptimer->timer_isrs;
|
||||
|
||||
/*
|
||||
* NOTE: we dont check the 'compare' variable here due to how the timer
|
||||
* is implemented on this chip. There is no way to force an output
|
||||
* compare, so if we are late setting the output compare (i.e. the timer
|
||||
* counter is already passed the output compare value), we use the NVIC
|
||||
* to set a pending interrupt. This means that there will be no compare
|
||||
* flag set, so all we do is check to see if the compare interrupt is
|
||||
* enabled.
|
||||
*/
|
||||
if (hwtimer->INTENCLR & NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT)) {
|
||||
hal_timer_chk_queue(bsptimer);
|
||||
/* XXX: Recommended by nordic to make sure interrupts are cleared */
|
||||
compare = hwtimer->EVENTS_COMPARE[NRF_TIMER_CC_INT];
|
||||
}
|
||||
|
||||
os_trace_exit_isr();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
static void
|
||||
hal_rtc_timer_irq_handler(struct nrf52_hal_timer *bsptimer)
|
||||
{
|
||||
uint32_t overflow;
|
||||
uint32_t compare;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
/* Check interrupt source. If set, clear them */
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT];
|
||||
if (compare) {
|
||||
rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT] = 0;
|
||||
}
|
||||
|
||||
overflow = rtctimer->EVENTS_OVRFLW;
|
||||
if (overflow) {
|
||||
rtctimer->EVENTS_OVRFLW = 0;
|
||||
bsptimer->tmr_cntr += (1UL << 24);
|
||||
}
|
||||
|
||||
/* Count # of timer isrs */
|
||||
++bsptimer->timer_isrs;
|
||||
|
||||
/*
|
||||
* NOTE: we dont check the 'compare' variable here due to how the timer
|
||||
* is implemented on this chip. There is no way to force an output
|
||||
* compare, so if we are late setting the output compare (i.e. the timer
|
||||
* counter is already passed the output compare value), we use the NVIC
|
||||
* to set a pending interrupt. This means that there will be no compare
|
||||
* flag set, so all we do is check to see if the compare interrupt is
|
||||
* enabled.
|
||||
*/
|
||||
hal_timer_chk_queue(bsptimer);
|
||||
|
||||
/* Recommended by nordic to make sure interrupts are cleared */
|
||||
compare = rtctimer->EVENTS_COMPARE[NRF_RTC_TIMER_CC_INT];
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
void
|
||||
nrf52_timer0_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
void
|
||||
nrf52_timer1_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
void
|
||||
nrf52_timer2_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer2);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
void
|
||||
nrf52_timer3_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer3);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
void
|
||||
nrf52_timer4_irq_handler(void)
|
||||
{
|
||||
hal_timer_irq_handler(&nrf52_hal_timer4);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
void
|
||||
nrf52_timer5_irq_handler(void)
|
||||
{
|
||||
hal_rtc_timer_irq_handler(&nrf52_hal_timer5);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* hal timer init
|
||||
*
|
||||
* Initialize platform specific timer items
|
||||
*
|
||||
* @param timer_num Timer number to initialize
|
||||
* @param cfg Pointer to platform specific configuration
|
||||
*
|
||||
* @return int 0: success; error code otherwise
|
||||
*/
|
||||
int
|
||||
hal_timer_init(int timer_num, void *cfg)
|
||||
{
|
||||
int rc;
|
||||
uint8_t irq_num;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
void *hwtimer;
|
||||
hal_timer_irq_handler_t irq_isr;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
/* If timer is enabled do not allow init */
|
||||
if (bsptimer->tmr_enabled) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (timer_num) {
|
||||
#if MYNEWT_VAL(TIMER_0)
|
||||
case 0:
|
||||
irq_num = TIMER0_IRQn;
|
||||
hwtimer = NRF_TIMER0;
|
||||
irq_isr = nrf52_timer0_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_1)
|
||||
case 1:
|
||||
irq_num = TIMER1_IRQn;
|
||||
hwtimer = NRF_TIMER1;
|
||||
irq_isr = nrf52_timer1_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_2)
|
||||
case 2:
|
||||
irq_num = TIMER2_IRQn;
|
||||
hwtimer = NRF_TIMER2;
|
||||
irq_isr = nrf52_timer2_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_3)
|
||||
case 3:
|
||||
irq_num = TIMER3_IRQn;
|
||||
hwtimer = NRF_TIMER3;
|
||||
irq_isr = nrf52_timer3_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_4)
|
||||
case 4:
|
||||
irq_num = TIMER4_IRQn;
|
||||
hwtimer = NRF_TIMER4;
|
||||
irq_isr = nrf52_timer4_irq_handler;
|
||||
break;
|
||||
#endif
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
case 5:
|
||||
irq_num = RTC0_IRQn;
|
||||
hwtimer = NRF_RTC0;
|
||||
irq_isr = nrf52_timer5_irq_handler;
|
||||
bsptimer->tmr_rtc = 1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
hwtimer = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (hwtimer == NULL) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bsptimer->tmr_reg = hwtimer;
|
||||
bsptimer->tmr_irq_num = irq_num;
|
||||
|
||||
/* Disable IRQ, set priority and set vector in table */
|
||||
NVIC_DisableIRQ(irq_num);
|
||||
NVIC_SetPriority(irq_num, (1 << __NVIC_PRIO_BITS) - 1);
|
||||
NVIC_SetVector(irq_num, (uint32_t)irq_isr);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer config
|
||||
*
|
||||
* Configure a timer to run at the desired frequency. This starts the timer.
|
||||
*
|
||||
* @param timer_num
|
||||
* @param freq_hz
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_config(int timer_num, uint32_t freq_hz)
|
||||
{
|
||||
int rc;
|
||||
uint8_t prescaler;
|
||||
uint32_t ctx;
|
||||
uint32_t div;
|
||||
uint32_t min_delta;
|
||||
uint32_t max_delta;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
NRF_RTC_Type *rtctimer;
|
||||
#endif
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
#if MYNEWT_VAL(TIMER_5)
|
||||
if (timer_num == 5) {
|
||||
/* NOTE: we only allow the RTC frequency to be set at 32768 */
|
||||
if (bsptimer->tmr_enabled || (freq_hz != 32768) ||
|
||||
(bsptimer->tmr_reg == NULL)) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
bsptimer->tmr_freq = freq_hz;
|
||||
bsptimer->tmr_enabled = 1;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
|
||||
/* Stop the timer first */
|
||||
rtctimer->TASKS_STOP = 1;
|
||||
|
||||
/* Always no prescaler */
|
||||
rtctimer->PRESCALER = 0;
|
||||
|
||||
/* Clear overflow events and set overflow interrupt */
|
||||
rtctimer->EVENTS_OVRFLW = 0;
|
||||
rtctimer->INTENSET = RTC_INTENSET_OVRFLW_Msk;
|
||||
|
||||
/* Start the timer */
|
||||
rtctimer->TASKS_START = 1;
|
||||
|
||||
/* Set isr in vector table and enable interrupt */
|
||||
NVIC_EnableIRQ(bsptimer->tmr_irq_num);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set timer to desired frequency */
|
||||
div = NRF52_MAX_TIMER_FREQ / freq_hz;
|
||||
|
||||
/*
|
||||
* Largest prescaler is 2^9 and must make sure frequency not too high.
|
||||
* If hwtimer is NULL it means that the timer was not initialized prior
|
||||
* to call.
|
||||
*/
|
||||
if (bsptimer->tmr_enabled || (div == 0) || (div > 512) ||
|
||||
(bsptimer->tmr_reg == NULL)) {
|
||||
rc = EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (div == 1) {
|
||||
prescaler = 0;
|
||||
} else {
|
||||
/* Find closest prescaler */
|
||||
for (prescaler = 1; prescaler < 10; ++prescaler) {
|
||||
if (div <= (1 << prescaler)) {
|
||||
min_delta = div - (1 << (prescaler - 1));
|
||||
max_delta = (1 << prescaler) - div;
|
||||
if (min_delta < max_delta) {
|
||||
prescaler -= 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now set the actual frequency */
|
||||
bsptimer->tmr_freq = NRF52_MAX_TIMER_FREQ / (1 << prescaler);
|
||||
bsptimer->tmr_enabled = 1;
|
||||
|
||||
/* disable interrupts */
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
/* Make sure HFXO is started */
|
||||
if ((NRF_CLOCK->HFCLKSTAT &
|
||||
(CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) !=
|
||||
(CLOCK_HFCLKSTAT_SRC_Msk | CLOCK_HFCLKSTAT_STATE_Msk)) {
|
||||
NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
|
||||
NRF_CLOCK->TASKS_HFCLKSTART = 1;
|
||||
while (1) {
|
||||
if ((NRF_CLOCK->EVENTS_HFCLKSTARTED) != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
hwtimer = bsptimer->tmr_reg;
|
||||
|
||||
/* Stop the timer first */
|
||||
hwtimer->TASKS_STOP = 1;
|
||||
|
||||
/* Put the timer in timer mode using 32 bits. */
|
||||
hwtimer->MODE = TIMER_MODE_MODE_Timer;
|
||||
hwtimer->BITMODE = TIMER_BITMODE_BITMODE_32Bit;
|
||||
|
||||
/* Set the pre-scalar */
|
||||
hwtimer->PRESCALER = prescaler;
|
||||
|
||||
/* Start the timer */
|
||||
hwtimer->TASKS_START = 1;
|
||||
|
||||
NVIC_EnableIRQ(bsptimer->tmr_irq_num);
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer deinit
|
||||
*
|
||||
* De-initialize a HW timer.
|
||||
*
|
||||
* @param timer_num
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_deinit(int timer_num)
|
||||
{
|
||||
int rc;
|
||||
uint32_t ctx;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
NRF_TIMER_Type *hwtimer;
|
||||
NRF_RTC_Type *rtctimer;
|
||||
|
||||
rc = 0;
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
if (bsptimer->tmr_rtc) {
|
||||
rtctimer = (NRF_RTC_Type *)bsptimer->tmr_reg;
|
||||
rtctimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_RTC_TIMER_CC_INT);
|
||||
rtctimer->TASKS_STOP = 1;
|
||||
} else {
|
||||
hwtimer = (NRF_TIMER_Type *)bsptimer->tmr_reg;
|
||||
hwtimer->INTENCLR = NRF_TIMER_INT_MASK(NRF_TIMER_CC_INT);
|
||||
hwtimer->TASKS_STOP = 1;
|
||||
}
|
||||
bsptimer->tmr_enabled = 0;
|
||||
bsptimer->tmr_reg = NULL;
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer get resolution
|
||||
*
|
||||
* Get the resolution of the timer. This is the timer period, in nanoseconds
|
||||
*
|
||||
* @param timer_num
|
||||
*
|
||||
* @return uint32_t The
|
||||
*/
|
||||
uint32_t
|
||||
hal_timer_get_resolution(int timer_num)
|
||||
{
|
||||
int rc;
|
||||
uint32_t resolution;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
resolution = 1000000000 / bsptimer->tmr_freq;
|
||||
return resolution;
|
||||
|
||||
err:
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer read
|
||||
*
|
||||
* Returns the timer counter. NOTE: if the timer is a 16-bit timer, only
|
||||
* the lower 16 bits are valid. If the timer is a 64-bit timer, only the
|
||||
* low 32-bits are returned.
|
||||
*
|
||||
* @return uint32_t The timer counter register.
|
||||
*/
|
||||
uint32_t
|
||||
hal_timer_read(int timer_num)
|
||||
{
|
||||
int rc;
|
||||
uint32_t tcntr;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
if (bsptimer->tmr_rtc) {
|
||||
tcntr = hal_timer_read_bsptimer(bsptimer);
|
||||
} else {
|
||||
tcntr = nrf_read_timer_cntr(bsptimer->tmr_reg);
|
||||
}
|
||||
|
||||
return tcntr;
|
||||
|
||||
/* Assert here since there is no invalid return code */
|
||||
err:
|
||||
assert(0);
|
||||
rc = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer delay
|
||||
*
|
||||
* Blocking delay for n ticks
|
||||
*
|
||||
* @param timer_num
|
||||
* @param ticks
|
||||
*
|
||||
* @return int 0 on success; error code otherwise.
|
||||
*/
|
||||
int
|
||||
hal_timer_delay(int timer_num, uint32_t ticks)
|
||||
{
|
||||
uint32_t until;
|
||||
|
||||
until = hal_timer_read(timer_num) + ticks;
|
||||
while ((int32_t)(hal_timer_read(timer_num) - until) <= 0) {
|
||||
/* Loop here till finished */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Initialize the HAL timer structure with the callback and the callback
|
||||
* argument. Also initializes the HW specific timer pointer.
|
||||
*
|
||||
* @param cb_func
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_set_cb(int timer_num, struct hal_timer *timer, hal_timer_cb cb_func,
|
||||
void *arg)
|
||||
{
|
||||
int rc;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
NRF52_HAL_TIMER_RESOLVE(timer_num, bsptimer);
|
||||
|
||||
timer->cb_func = cb_func;
|
||||
timer->cb_arg = arg;
|
||||
timer->link.tqe_prev = NULL;
|
||||
timer->bsp_timer = bsptimer;
|
||||
|
||||
rc = 0;
|
||||
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
hal_timer_start(struct hal_timer *timer, uint32_t ticks)
|
||||
{
|
||||
int rc;
|
||||
uint32_t tick;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
/* Set the tick value at which the timer should expire */
|
||||
bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer;
|
||||
if (bsptimer->tmr_rtc) {
|
||||
tick = hal_timer_read_bsptimer(bsptimer) + ticks;
|
||||
} else {
|
||||
tick = nrf_read_timer_cntr(bsptimer->tmr_reg) + ticks;
|
||||
}
|
||||
rc = hal_timer_start_at(timer, tick);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
hal_timer_start_at(struct hal_timer *timer, uint32_t tick)
|
||||
{
|
||||
uint32_t ctx;
|
||||
struct hal_timer *entry;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
if ((timer == NULL) || (timer->link.tqe_prev != NULL) ||
|
||||
(timer->cb_func == NULL)) {
|
||||
return EINVAL;
|
||||
}
|
||||
bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer;
|
||||
timer->expiry = tick;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
if (TAILQ_EMPTY(&bsptimer->hal_timer_q)) {
|
||||
TAILQ_INSERT_HEAD(&bsptimer->hal_timer_q, timer, link);
|
||||
} else {
|
||||
TAILQ_FOREACH(entry, &bsptimer->hal_timer_q, link) {
|
||||
if ((int32_t)(timer->expiry - entry->expiry) < 0) {
|
||||
TAILQ_INSERT_BEFORE(entry, timer, link);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!entry) {
|
||||
TAILQ_INSERT_TAIL(&bsptimer->hal_timer_q, timer, link);
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is the head, we need to set new OCMP */
|
||||
if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) {
|
||||
nrf_timer_set_ocmp(bsptimer, timer->expiry);
|
||||
}
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hal timer stop
|
||||
*
|
||||
* Stop a timer.
|
||||
*
|
||||
* @param timer
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int
|
||||
hal_timer_stop(struct hal_timer *timer)
|
||||
{
|
||||
uint32_t ctx;
|
||||
int reset_ocmp;
|
||||
struct hal_timer *entry;
|
||||
struct nrf52_hal_timer *bsptimer;
|
||||
|
||||
if (timer == NULL) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
bsptimer = (struct nrf52_hal_timer *)timer->bsp_timer;
|
||||
|
||||
__HAL_DISABLE_INTERRUPTS(ctx);
|
||||
|
||||
if (timer->link.tqe_prev != NULL) {
|
||||
reset_ocmp = 0;
|
||||
if (timer == TAILQ_FIRST(&bsptimer->hal_timer_q)) {
|
||||
/* If first on queue, we will need to reset OCMP */
|
||||
entry = TAILQ_NEXT(timer, link);
|
||||
reset_ocmp = 1;
|
||||
}
|
||||
TAILQ_REMOVE(&bsptimer->hal_timer_q, timer, link);
|
||||
timer->link.tqe_prev = NULL;
|
||||
if (reset_ocmp) {
|
||||
if (entry) {
|
||||
nrf_timer_set_ocmp((struct nrf52_hal_timer *)entry->bsp_timer,
|
||||
entry->expiry);
|
||||
} else {
|
||||
if (bsptimer->tmr_rtc) {
|
||||
nrf_rtc_disable_ocmp((NRF_RTC_Type *)bsptimer->tmr_reg);
|
||||
} else {
|
||||
nrf_timer_disable_ocmp(bsptimer->tmr_reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__HAL_ENABLE_INTERRUPTS(ctx);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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 <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "task.h"
|
||||
#include "bsp.h"
|
||||
#include "nordic_common.h"
|
||||
#include "nrf_drv_clock.h"
|
||||
#include "sdk_errors.h"
|
||||
#include "app_error.h"
|
||||
#include "bsp/cmsis_nvic.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
|
||||
/* Relocate ISR vector from flash to RAM */
|
||||
NVIC_Relocate();
|
||||
|
||||
/* Initialize clock driver for better time accuracy in FREERTOS */
|
||||
err_code = nrf_drv_clock_init();
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
/* Configure LED-pins as outputs */
|
||||
bsp_board_leds_init();
|
||||
bsp_board_leds_off();
|
||||
|
||||
/* Activate deep sleep mode */
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
void start_nimble(void);
|
||||
start_nimble();
|
||||
|
||||
/* Start FreeRTOS scheduler. */
|
||||
vTaskStartScheduler();
|
||||
|
||||
while (true)
|
||||
{
|
||||
/* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
|
||||
* in vTaskStartScheduler function. */
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,348 @@
|
||||
/*
|
||||
* 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 <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "os/os.h"
|
||||
#include "FreeRTOS.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
|
||||
static struct os_eventq dflt_evq;
|
||||
|
||||
static inline bool in_isr()
|
||||
{
|
||||
return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;
|
||||
}
|
||||
|
||||
int
|
||||
os_started(void)
|
||||
{
|
||||
return xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED;
|
||||
}
|
||||
|
||||
struct os_task *
|
||||
os_sched_get_current_task(void)
|
||||
{
|
||||
return xTaskGetCurrentTaskHandle();
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_mutex_init(struct os_mutex *mu)
|
||||
{
|
||||
if (!mu) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
mu->handle = xSemaphoreCreateRecursiveMutex();
|
||||
assert(mu->handle);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_mutex_release(struct os_mutex *mu)
|
||||
{
|
||||
if (!mu) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
assert(mu->handle);
|
||||
|
||||
if (in_isr()) {
|
||||
assert(0);
|
||||
} else {
|
||||
if (xSemaphoreGiveRecursive(mu->handle) != pdPASS) {
|
||||
return OS_BAD_MUTEX;
|
||||
}
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_mutex_pend(struct os_mutex *mu, uint32_t timeout)
|
||||
{
|
||||
if (!mu) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
assert(mu->handle);
|
||||
|
||||
if (in_isr()) {
|
||||
assert(0);
|
||||
} else {
|
||||
if (xSemaphoreTakeRecursive(mu->handle, timeout) != pdPASS) {
|
||||
return OS_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_sem_init(struct os_sem *sem, uint16_t tokens)
|
||||
{
|
||||
if (!sem) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
sem->handle = xSemaphoreCreateCounting(128, tokens);
|
||||
assert(sem->handle);
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_sem_release(struct os_sem *sem)
|
||||
{
|
||||
BaseType_t ret;
|
||||
BaseType_t woken;
|
||||
|
||||
if (!sem) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
assert(sem->handle);
|
||||
|
||||
if (in_isr()) {
|
||||
ret = xSemaphoreGiveFromISR(sem->handle, &woken);
|
||||
assert(ret == pdPASS);
|
||||
|
||||
portYIELD_FROM_ISR(woken);
|
||||
} else {
|
||||
ret = xSemaphoreGive(sem->handle);
|
||||
assert(ret == pdPASS);
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
os_error_t
|
||||
os_sem_pend(struct os_sem *sem, uint32_t timeout)
|
||||
{
|
||||
BaseType_t woken;
|
||||
|
||||
if (!sem) {
|
||||
return OS_INVALID_PARM;
|
||||
}
|
||||
|
||||
assert(sem->handle);
|
||||
|
||||
if (in_isr()) {
|
||||
assert(timeout == 0);
|
||||
if (xSemaphoreTakeFromISR(sem->handle, &woken) != pdPASS) {
|
||||
portYIELD_FROM_ISR(woken);
|
||||
return OS_TIMEOUT;
|
||||
}
|
||||
portYIELD_FROM_ISR(woken);
|
||||
} else {
|
||||
if (xSemaphoreTake(sem->handle, timeout) != pdPASS) {
|
||||
return OS_TIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
uint16_t
|
||||
os_sem_get_count(struct os_sem *sem)
|
||||
{
|
||||
/* XXX FreeRTOS 9.x added dedicated API for this - it's the same as below */
|
||||
return uxQueueMessagesWaiting(sem->handle);
|
||||
}
|
||||
|
||||
struct os_eventq *
|
||||
os_eventq_dflt_get(void)
|
||||
{
|
||||
if (!dflt_evq.q) {
|
||||
dflt_evq.q = xQueueCreate(32, sizeof(struct os_event *));
|
||||
}
|
||||
|
||||
return &dflt_evq;
|
||||
}
|
||||
|
||||
void
|
||||
os_eventq_init(struct os_eventq *evq)
|
||||
{
|
||||
evq->q = xQueueCreate(32, sizeof(struct os_event *));
|
||||
}
|
||||
|
||||
struct os_event *
|
||||
os_eventq_get(struct os_eventq *evq)
|
||||
{
|
||||
struct os_event *ev;
|
||||
BaseType_t ret;
|
||||
|
||||
ret = xQueueReceive(evq->q, &ev, portMAX_DELAY);
|
||||
assert(ret == pdPASS);
|
||||
|
||||
ev->ev_queued = 0;
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
void
|
||||
os_eventq_put(struct os_eventq *evq, struct os_event *ev)
|
||||
{
|
||||
BaseType_t ret;
|
||||
|
||||
if (OS_EVENT_QUEUED(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ev->ev_queued = 1;
|
||||
|
||||
ret = xQueueSendToBack(evq->q, &ev, 0);
|
||||
assert(ret == pdPASS);
|
||||
}
|
||||
|
||||
void
|
||||
os_eventq_remove(struct os_eventq *evq, struct os_event *ev)
|
||||
{
|
||||
struct os_event *tmp_ev;
|
||||
BaseType_t ret;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
if (!OS_EVENT_QUEUED(ev)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX We cannot extract element from inside FreeRTOS queue so as a quick
|
||||
* workaround we'll just remove all elements and add them back except the
|
||||
* one we need to remove. This is silly, but works for now - we probably
|
||||
* better use counting semaphore with os_queue to handle this in future.
|
||||
*/
|
||||
|
||||
vPortEnterCritical();
|
||||
|
||||
count = uxQueueMessagesWaiting(evq->q);
|
||||
for (i = 0; i < count; i++) {
|
||||
ret = xQueueReceive(evq->q, &tmp_ev, 0);
|
||||
assert(ret == pdPASS);
|
||||
|
||||
if (tmp_ev == ev) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = xQueueSendToBack(evq->q, &tmp_ev, 0);
|
||||
assert(ret == pdPASS);
|
||||
}
|
||||
|
||||
vPortExitCritical();
|
||||
|
||||
ev->ev_queued = 0;
|
||||
}
|
||||
|
||||
void
|
||||
os_eventq_run(struct os_eventq *evq)
|
||||
{
|
||||
struct os_event *ev;
|
||||
|
||||
ev = os_eventq_get(evq);
|
||||
assert(ev->ev_cb != NULL);
|
||||
|
||||
ev->ev_cb(ev);
|
||||
}
|
||||
|
||||
static void
|
||||
os_callout_timer_cb(TimerHandle_t timer)
|
||||
{
|
||||
struct os_callout *c;
|
||||
|
||||
c = pvTimerGetTimerID(timer);
|
||||
assert(c);
|
||||
|
||||
if (c->c_evq) {
|
||||
os_eventq_put(c->c_evq, &c->c_ev);
|
||||
} else {
|
||||
c->c_ev.ev_cb(&c->c_ev);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
os_callout_init(struct os_callout *c, struct os_eventq *evq,
|
||||
os_event_fn *ev_cb, void *ev_arg)
|
||||
{
|
||||
memset(c, 0, sizeof(*c));
|
||||
c->c_ev.ev_cb = ev_cb;
|
||||
c->c_ev.ev_arg = ev_arg;
|
||||
c->c_evq = evq;
|
||||
c->c_timer = xTimerCreate("co", 1, pdFALSE, c, os_callout_timer_cb);
|
||||
}
|
||||
|
||||
int
|
||||
os_callout_reset(struct os_callout *c, int32_t ticks)
|
||||
{
|
||||
BaseType_t woken1, woken2, woken3;
|
||||
|
||||
if (ticks < 0) {
|
||||
return OS_EINVAL;
|
||||
}
|
||||
|
||||
if (ticks == 0) {
|
||||
ticks = 1;
|
||||
}
|
||||
|
||||
c->c_ticks = os_time_get() + ticks;
|
||||
|
||||
if (in_isr()) {
|
||||
xTimerStopFromISR(c->c_timer, &woken1);
|
||||
xTimerChangePeriodFromISR(c->c_timer, ticks, &woken2);
|
||||
xTimerResetFromISR(c->c_timer, &woken3);
|
||||
|
||||
portYIELD_FROM_ISR(woken1 || woken2 || woken3);
|
||||
} else {
|
||||
xTimerStop(c->c_timer, portMAX_DELAY);
|
||||
xTimerChangePeriod(c->c_timer, ticks, portMAX_DELAY);
|
||||
xTimerReset(c->c_timer, portMAX_DELAY);
|
||||
}
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
os_callout_queued(struct os_callout *c)
|
||||
{
|
||||
return xTimerIsTimerActive(c->c_timer) == pdTRUE;
|
||||
}
|
||||
|
||||
void
|
||||
os_callout_stop(struct os_callout *c)
|
||||
{
|
||||
xTimerStop(c->c_timer, portMAX_DELAY);
|
||||
}
|
||||
|
||||
os_time_t
|
||||
os_time_get(void)
|
||||
{
|
||||
return xTaskGetTickCountFromISR();
|
||||
}
|
||||
|
||||
int
|
||||
os_time_ms_to_ticks(uint32_t ms, uint32_t *out_ticks)
|
||||
{
|
||||
*out_ticks = ms;
|
||||
|
||||
return OS_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user