mbed-os/cmsis/device/rtos/TOOLCHAIN_IAR/mbed_boot_iar.c

175 lines
5.3 KiB
C

/* mbed Microcontroller Library
* Copyright (c) 2018-2018 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* 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.
*/
#include "cmsis.h"
#include "mbed_error.h"
#include "mbed_boot.h"
#if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000)
#include <DLib_Threads.h>
#endif
#include "mbed_rtos_storage.h"
#include "cmsis_os2.h"
/* Defined by linker script */
#pragma section="CSTACK"
#pragma section="HEAP"
extern void *__vector_table[];
extern int __low_level_init(void);
extern void __iar_data_init3(void);
extern __weak void __iar_init_core(void);
extern __weak void __iar_init_vfp(void);
extern void __iar_dynamic_initialization(void);
/*
* mbed entry point for the IAR toolchain
*
* Override __iar_program_start to run code before main.
* This is the first function called after the low level
* target initialization, so RAM has not been setup yet.
*
* Details on what this function are supposed to do can
* be found by looking at the IAR source for this file.
*
* IAR source files for ARM instruction set:
* <IAR>\arm\src\lib\arm\cstartup.s
* <IAR>\arm\src\lib\arm\cmain.s
*
* IAR source files for THUMB instruction set:
* <IAR>\arm\src\lib\thumb\cmain.s
* <IAR>\arm\src\lib\thumb\cstartup_M.s
*/
#pragma required=__vector_table
void __iar_program_start(void)
{
/* the calls below are normally made in IAR cstartup */
__iar_init_core();
__iar_init_vfp();
/* the calls below are normally made in IAR cmain
*
* The function "__low_level_init" is a user overrideable hook
* that does nothing by default. Returning zero means that
* ram initialization should be skipped. Skipping ram initialization
* is not allowed by mbed.
*
* The function "__iar_data_init3" is an IAR function which
* initializes ram.
*
*/
__low_level_init();
__iar_data_init3();
/* mbed specific code */
mbed_heap_start = (unsigned char *)__section_begin("HEAP");
mbed_heap_size = (uint32_t)__section_size("HEAP");
mbed_stack_isr_start = (unsigned char *)__section_begin("CSTACK");
mbed_stack_isr_size = (uint32_t)__section_size("CSTACK");
mbed_init();
mbed_rtos_start();
}
void mbed_toolchain_init(void)
{
#if defined(__IAR_SYSTEMS_ICC__ ) && (__VER__ >= 8000000) && !defined(MBED_RTOS_SINGLE_THREAD)
__iar_Initlocks();
#endif
/* Run the C++ global object constructors */
__iar_dynamic_initialization();
}
/* Thread safety */
static osMutexId_t std_mutex_id_sys[_MAX_LOCK] = {0};
static mbed_rtos_storage_mutex_t std_mutex_sys[_MAX_LOCK] = {0};
#define _FOPEN_MAX 10
static osMutexId_t std_mutex_id_file[_FOPEN_MAX] = {0};
static mbed_rtos_storage_mutex_t std_mutex_file[_FOPEN_MAX] = {0};
void __iar_system_Mtxinit(__iar_Rmtx *mutex) /* Initialize a system lock */
{
osMutexAttr_t attr;
uint32_t index;
for (index = 0; index < _MAX_LOCK; index++) {
if (0 == std_mutex_id_sys[index]) {
attr.name = "system_mutex";
attr.cb_mem = &std_mutex_sys[index];
attr.cb_size = sizeof(std_mutex_sys[index]);
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
std_mutex_id_sys[index] = osMutexNew(&attr);
*mutex = (__iar_Rmtx *)&std_mutex_id_sys[index];
return;
}
}
/* This should never happen */
error("Not enough mutexes\n");
}
void __iar_system_Mtxdst(__iar_Rmtx *mutex) /* Destroy a system lock */
{
osMutexDelete(*(osMutexId_t *)*mutex);
*mutex = 0;
}
void __iar_system_Mtxlock(__iar_Rmtx *mutex) /* Lock a system lock */
{
osMutexAcquire(*(osMutexId_t *)*mutex, osWaitForever);
}
void __iar_system_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a system lock */
{
osMutexRelease(*(osMutexId_t *)*mutex);
}
void __iar_file_Mtxinit(__iar_Rmtx *mutex) /* Initialize a file lock */
{
osMutexAttr_t attr;
uint32_t index;
for (index = 0; index < _FOPEN_MAX; index++) {
if (0 == std_mutex_id_file[index]) {
attr.name = "file_mutex";
attr.cb_mem = &std_mutex_file[index];
attr.cb_size = sizeof(std_mutex_file[index]);
attr.attr_bits = osMutexRecursive | osMutexPrioInherit | osMutexRobust;
std_mutex_id_file[index] = osMutexNew(&attr);
*mutex = (__iar_Rmtx *)&std_mutex_id_file[index];
return;
}
}
/* The variable _FOPEN_MAX needs to be increased */
error("Not enough mutexes\n");
}
void __iar_file_Mtxdst(__iar_Rmtx *mutex) /* Destroy a file lock */
{
osMutexDelete(*(osMutexId_t *)*mutex);
*mutex = 0;
}
void __iar_file_Mtxlock(__iar_Rmtx *mutex) /* Lock a file lock */
{
osMutexAcquire(*(osMutexId_t *)*mutex, osWaitForever);
}
void __iar_file_Mtxunlock(__iar_Rmtx *mutex) /* Unlock a file lock */
{
osMutexRelease(*(osMutexId_t *)*mutex);
}