2020-02-05 06:57:40 -05:00
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed 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.
# pragma once
# include "esp_attr.h"
2020-02-05 09:40:15 -05:00
# include "soc/soc_caps.h"
# include "hal/cpu_hal.h"
2020-02-13 07:43:23 -05:00
# include "sdkconfig.h"
2020-02-16 08:29:29 -05:00
# ifdef __cplusplus
extern " C " {
# endif
2020-02-05 09:40:15 -05:00
extern bool g_spiram_ok ; // [refactor-todo] better way to communicate this from port layer to common startup code
// Port layer defines the entry point. It then transfer control to a `sys_startup_fn_t`, stored in this
// array, one per core.
typedef void ( * sys_startup_fn_t ) ( void ) ;
2020-02-13 07:43:23 -05:00
2021-03-01 23:59:44 -05:00
/* This array of per-CPU system layer startup functions is initialized in the non-port part of esp_system */
2020-02-13 07:43:23 -05:00
# if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
2021-03-01 23:59:44 -05:00
extern sys_startup_fn_t const g_startup_fn [ SOC_CPU_CORES_NUM ] ;
2020-02-13 07:43:23 -05:00
# else
2021-03-01 23:59:44 -05:00
extern sys_startup_fn_t const g_startup_fn [ 1 ] ;
2020-02-13 07:43:23 -05:00
# endif
2020-02-05 09:40:15 -05:00
// Utility to execute `sys_startup_fn_t` for the current core.
# define SYS_STARTUP_FN() ((*g_startup_fn[(cpu_hal_get_core_id())])())
2020-02-13 07:43:23 -05:00
# if !CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE
2020-02-05 09:40:15 -05:00
void startup_resume_other_cores ( void ) ;
2020-02-13 07:43:23 -05:00
# endif
2020-02-05 09:40:15 -05:00
2020-02-05 06:57:40 -05:00
typedef struct {
void ( * fn ) ( void ) ;
uint32_t cores ;
} esp_system_init_fn_t ;
/*
* Declare an component initialization function that will execute on the specified cores ( ex . if BIT0 = = 1 , will execute
* on CORE0 , CORE1 if BIT1 and so on ) .
2020-11-10 02:40:01 -05:00
*
2020-02-05 06:57:40 -05:00
* @ note Initialization functions should be placed in a compilation unit where at least one other
* symbol is referenced ' meaningfully ' in another compilation unit , otherwise this gets discarded during linking . ( By
* ' meaningfully ' we mean the reference should not itself get optimized out by the compiler / discarded by the linker ) .
*/
# define ESP_SYSTEM_INIT_FN(f, c, ...) \
static void __attribute__ ( ( used ) ) __VA_ARGS__ __esp_system_init_fn_ # # f ( void ) ; \
static __attribute__ ( ( used ) ) esp_system_init_fn_t _SECTION_ATTR_IMPL ( " .esp_system_init_fn " , f ) \
esp_system_init_fn_ # # f = { . fn = ( __esp_system_init_fn_ # # f ) , . cores = ( c ) } ; \
2020-11-10 02:40:01 -05:00
static __attribute__ ( ( used ) ) __VA_ARGS__ void __esp_system_init_fn_ # # f ( void ) // [refactor-todo] this can be made public API if we allow components to declare init functions,
2020-02-05 06:57:40 -05:00
// instead of calling them explicitly
2020-11-10 02:40:01 -05:00
extern uint64_t g_startup_time ; // Startup time that serves as the point of origin for system time. Should be set by the entry
2020-06-23 04:46:06 -04:00
// function in the port layer. May be 0 as well if this is not backed by a persistent counter, in which case
// startup time = system time = 0 at the point the entry function sets this variable.
2020-02-16 08:29:29 -05:00
# ifdef __cplusplus
}
# endif