Commit fd28c460 authored by Bogdan Kolbov's avatar Bogdan Kolbov
Browse files

RELEASE: v0.6.0

parents 1f5c158b 13a6925f
Showing with 24587 additions and 2 deletions
+24587 -2
## Описание
*NIIETCM4 PD (Peripheral driver)* - это комплект драйверов, предназначеных для
ускорения и упрощения работы со внутренними периферийными устройствами
микроконтроллеров на базе ядра ARM Cortex-M4 производства ОАО "НИИЭТ".
......@@ -18,7 +19,13 @@
- UART
- TIMER
- RTC
- BOOTFLASH
- USERFLASH
- EXTMEM
## Загрузки
Текущую версию драйвера можно скачать по данной ссылке: [NIIETCM4 Peripheral Driver v0.6.0](https://bitbucket.org/niietcm4/niietcm4_pd/downloads/niietcm4_pd_v0.6.0.zip).
Предыдущие версии могут быть найдены на странице [Загрузки](https://bitbucket.org/niietcm4/niietcm4_pd/downloads/).
## Контакты
Разработка ведется полностью открыто - проект расположен в публичном
......
# Информация о релизах
# v0.6.0
### Добавлено:
- драйвер для работы с загрузочной флеш (BOOTFLASH)
- драйвер для работы с пользовательской флеш (USERFLASH)
- драйвер для работы с внешней памятью (EXTMEM)
### Исключено:
### Исправлено:
- мелкие неточности документации блока UART
# v0.5.0
### Добавлено:
......
......@@ -38,7 +38,7 @@ PROJECT_NAME = "NIIETCM4 PD"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v0.5.0
PROJECT_NUMBER = v0.6.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
......
......@@ -38,7 +38,7 @@ PROJECT_NAME = "NIIETCM4 PD"
# could be handy for archiving the generated documentation or if some version
# control system is used.
PROJECT_NUMBER = v0.5.0
PROJECT_NUMBER = v0.6.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
......
/* Linker script to configure memory regions.
* Need modifying for a specific board.
* FLASH.ORIGIN: starting address of flash
* FLASH.LENGTH: length of flash
* RAM.ORIGIN: starting address of RAM bank 0
* RAM.LENGTH: length of RAM bank 0
*/
MEMORY
{
FLASH (rx) : ORIGIN = 0x0, LENGTH = 0x100000 /* 1M */
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x030000 /* 192K */
}
/* Linker script to place sections and symbol values. Should be used together
* with other linker script that defines memory regions FLASH and RAM.
* It references following symbols, which must be defined in code:
* Reset_Handler : Entry of reset handler
*
* It defines following symbols, which code can use without definition:
* __exidx_start
* __exidx_end
* __copy_table_start__
* __copy_table_end__
* __zero_table_start__
* __zero_table_end__
* __etext
* __data_start__
* __preinit_array_start
* __preinit_array_end
* __init_array_start
* __init_array_end
* __fini_array_start
* __fini_array_end
* __data_end__
* __bss_start__
* __bss_end__
* __end__
* end
* __HeapLimit
* __StackLimit
* __StackTop
* __stack
*/
ENTRY(Reset_Handler)
SECTIONS
{
.text :
{
KEEP(*(.isr_vector))
*(.text*)
KEEP(*(.init))
KEEP(*(.fini))
/* .ctors */
*crtbegin.o(.ctors)
*crtbegin?.o(.ctors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
*(SORT(.ctors.*))
*(.ctors)
/* .dtors */
*crtbegin.o(.dtors)
*crtbegin?.o(.dtors)
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
*(SORT(.dtors.*))
*(.dtors)
*(.rodata*)
KEEP(*(.eh_frame*))
} > FLASH
.ARM.extab :
{
*(.ARM.extab* .gnu.linkonce.armextab.*)
} > FLASH
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > FLASH
__exidx_end = .;
/* To copy multiple ROM to RAM sections,
* uncomment .copy.table section and,
* define __STARTUP_COPY_MULTIPLE in startup_ARMCMx.S */
/*
.copy.table :
{
. = ALIGN(4);
__copy_table_start__ = .;
LONG (__etext)
LONG (__data_start__)
LONG (__data_end__ - __data_start__)
LONG (__etext2)
LONG (__data2_start__)
LONG (__data2_end__ - __data2_start__)
__copy_table_end__ = .;
} > FLASH
*/
/* To clear multiple BSS sections,
* uncomment .zero.table section and,
* define __STARTUP_CLEAR_BSS_MULTIPLE in startup_ARMCMx.S */
/*
.zero.table :
{
. = ALIGN(4);
__zero_table_start__ = .;
LONG (__bss_start__)
LONG (__bss_end__ - __bss_start__)
LONG (__bss2_start__)
LONG (__bss2_end__ - __bss2_start__)
__zero_table_end__ = .;
} > FLASH
*/
__etext = .;
.data : AT (__etext)
{
__data_start__ = .;
*(vtable)
*(.data*)
. = ALIGN(4);
/* preinit data */
PROVIDE_HIDDEN (__preinit_array_start = .);
KEEP(*(.preinit_array))
PROVIDE_HIDDEN (__preinit_array_end = .);
. = ALIGN(4);
/* init data */
PROVIDE_HIDDEN (__init_array_start = .);
KEEP(*(SORT(.init_array.*)))
KEEP(*(.init_array))
PROVIDE_HIDDEN (__init_array_end = .);
. = ALIGN(4);
/* finit data */
PROVIDE_HIDDEN (__fini_array_start = .);
KEEP(*(SORT(.fini_array.*)))
KEEP(*(.fini_array))
PROVIDE_HIDDEN (__fini_array_end = .);
KEEP(*(.jcr*))
. = ALIGN(4);
/* All data end */
__data_end__ = .;
} > RAM
.bss :
{
. = ALIGN(4);
__bss_start__ = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
__bss_end__ = .;
} > RAM
.heap (COPY):
{
__end__ = .;
PROVIDE(end = .);
*(.heap*)
__HeapLimit = .;
} > RAM
/* .stack_dummy section doesn't contains any symbols. It is only
* used for linker to calculate size of stack sections, and assign
* values to stack symbols later */
.stack_dummy (COPY):
{
*(.stack*)
} > RAM
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
__StackTop = ORIGIN(RAM) + LENGTH(RAM);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
/* Check if data + heap + stack exceeds RAM limit */
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack")
}
/* ----------------------------------------------------------------------
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* $Date: 11. November 2010
* $Revision: V1.0.2
*
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
*
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Version 1.0.2 2010/11/11
* Documentation updated.
*
* Version 1.0.1 2010/10/05
* Production release and review comments incorporated.
*
* Version 1.0.0 2010/09/20
* Production release and review comments incorporated.
* -------------------------------------------------------------------- */
#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H
#include "arm_math.h"
extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
extern const q31_t realCoefAQ31[1024];
extern const q31_t realCoefBQ31[1024];
extern const float32_t twiddleCoef[6144];
extern const q31_t twiddleCoefQ31[6144];
extern const q15_t twiddleCoefQ15[6144];
#endif /* ARM_COMMON_TABLES_H */
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
return(op1);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */
!<arch>
/ 1332941704 0 0 0 6332 `
.syntax unified
.arch armv7e-m
.section .stack
.align 3
#ifdef __STACK_SIZE
.equ Stack_Size, __STACK_SIZE
#else
.equ Stack_Size, 0xc00
#endif
.globl __StackTop
.globl __StackLimit
__StackLimit:
.space Stack_Size
.size __StackLimit, . - __StackLimit
__StackTop:
.size __StackTop, . - __StackTop
.section .heap
.align 3
#ifdef __HEAP_SIZE
.equ Heap_Size, __HEAP_SIZE
#else
.equ Heap_Size, 0
#endif
.globl __HeapBase
.globl __HeapLimit
__HeapBase:
.if Heap_Size
.space Heap_Size
.endif
.size __HeapBase, . - __HeapBase
__HeapLimit:
.size __HeapLimit, . - __HeapLimit
.section .isr_vector
.align 2
.globl __isr_vector
__isr_vector:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long 0 /* Reserved */
.long SVC_Handler /* SVCall Handler */
.long DebugMon_Handler /* Debug Monitor Handler */
.long 0 /* Reserved */
.long PendSV_Handler /* PendSV Handler */
.long SysTick_Handler /* SysTick Handler */
/* External interrupts */
.long WWDG_IRQHandler
.long I2C0_IRQHandler
.long I2C1_IRQHandler
.long TIM0_IRQHandler
.long TIM1_IRQHandler
.long TIM2_IRQHandler
.long DMA_Stream0_IRQHandler
.long DMA_Stream1_IRQHandler
.long DMA_Stream2_IRQHandler
.long DMA_Stream3_IRQHandler
.long DMA_Stream4_IRQHandler
.long DMA_Stream5_IRQHandler
.long DMA_Stream6_IRQHandler
.long DMA_Stream7_IRQHandler
.long DMA_Stream8_IRQHandler
.long DMA_Stream9_IRQHandler
.long DMA_Stream10_IRQHandler
.long DMA_Stream11_IRQHandler
.long DMA_Stream12_IRQHandler
.long DMA_Stream13_IRQHandler
.long DMA_Stream14_IRQHandler
.long DMA_Stream15_IRQHandler
.long DMA_Stream16_IRQHandler
.long DMA_Stream17_IRQHandler
.long DMA_Stream18_IRQHandler
.long DMA_Stream19_IRQHandler
.long DMA_Stream20_IRQHandler
.long DMA_Stream21_IRQHandler
.long DMA_Stream22_IRQHandler
.long DMA_Stream23_IRQHandler
.long UART0_MX_IRQHandler
.long UART0_RX_IRQHandler
.long UART0_TX_IRQHandler
.long UART0_RT_IRQHandler
.long UART0_E_IRQHandler
.long UART0_IRQHandler
.long UART1_MX_IRQHandler
.long UART1_RX_IRQHandler
.long UART1_TX_IRQHandler
.long UART1_RT_IRQHandler
.long UART1_E_IRQHandler
.long UART1_IRQHandler
.long UART2_MX_IRQHandler
.long UART2_RX_IRQHandler
.long UART2_TX_IRQHandler
.long UART2_RT_IRQHandler
.long UART2_E_IRQHandler
.long UART2_IRQHandler
.long UART3_MX_IRQHandler
.long UART3_RX_IRQHandler
.long UART3_TX_IRQHandler
.long UART3_RT_IRQHandler
.long UART3_E_IRQHandler
.long UART3_IRQHandler
.long PWM0_IRQHandler
.long PWM0_HD_IRQHandler
.long PWM0_TZ_IRQHandler
.long PWM1_IRQHandler
.long PWM1_HD_IRQHandler
.long PWM1_TZ_IRQHandler
.long PWM2_IRQHandler
.long PWM2_HD_IRQHandler
.long PWM2_TZ_IRQHandler
.long PWM3_IRQHandler
.long PWM3_HD_IRQHandler
.long PWM3_TZ_IRQHandler
.long PWM4_IRQHandler
.long PWM4_HD_IRQHandler
.long PWM4_TZ_IRQHandler
.long PWM5_IRQHandler
.long PWM5_HD_IRQHandler
.long PWM5_TZ_IRQHandler
.long PWM6_IRQHandler
.long PWM6_HD_IRQHandler
.long PWM6_TZ_IRQHandler
.long PWM7_IRQHandler
.long PWM7_HD_IRQHandler
.long PWM7_TZ_IRQHandler
.long PWM8_IRQHandler
.long PWM8_HD_IRQHandler
.long PWM8_TZ_IRQHandler
.long ADC_SEQ0_IRQHandler
.long ADC_SEQ1_IRQHandler
.long ADC_SEQ2_IRQHandler
.long ADC_SEQ3_IRQHandler
.long ADC_SEQ4_IRQHandler
.long ADC_SEQ5_IRQHandler
.long ADC_SEQ6_IRQHandler
.long ADC_SEQ7_IRQHandler
.long ADC_CompInt_IRQHandler
.long CAP0_IRQHandler
.long CAP1_IRQHandler
.long CAP2_IRQHandler
.long CAP3_IRQHandler
.long CAP4_IRQHandler
.long CAP5_IRQHandler
.long QEP0_IRQHandler
.long QEP1_IRQHandler
.long BootFlash_IRQHandler
.long CMP0_IRQHandler
.long CMP1_IRQHandler
.long CMP2_IRQHandler
.long SPI0_IRQHandler
.long SPI1_IRQHandler
.long SPI2_IRQHandler
.long SPI3_IRQHandler
.long UserFlash_IRQHandler
.long GPIOA_IRQHandler
.long GPIOB_IRQHandler
.long GPIOC_IRQHandler
.long GPIOD_IRQHandler
.long GPIOE_IRQHandler
.long GPIOF_IRQHandler
.long GPIOG_IRQHandler
.long GPIOH_IRQHandler
.long Ethernet_IRQHandler
.long CAN0_IRQHandler
.long CAN1_IRQHandler
.long CAN2_IRQHandler
.long CAN3_IRQHandler
.long CAN4_IRQHandler
.long CAN5_IRQHandler
.long CAN6_IRQHandler
.long CAN7_IRQHandler
.long CAN8_IRQHandler
.long CAN9_IRQHandler
.long CAN10_IRQHandler
.long CAN11_IRQHandler
.long CAN12_IRQHandler
.long CAN13_IRQHandler
.long CAN14_IRQHandler
.long CAN15_IRQHandler
.long RTC_IRQHandler
.long USB_IRQHandler
.size __isr_vector, . - __isr_vector
.text
.thumb
.thumb_func
.align 2
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
/* Firstly it copies data from read only memory to RAM. There are two schemes
* to copy. One can copy more than one sections. Another can only copy
* one section. The former scheme needs more instructions and read-only
* data to implement than the latter.
* Macro __STARTUP_COPY_MULTIPLE is used to choose between two schemes. */
#ifdef __STARTUP_COPY_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of triplets, each of which specify:
* offset 0: LMA of start of a section to copy from
* offset 4: VMA of start of a section to copy to
* offset 8: size of the section to copy. Must be multiply of 4
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r4, =__copy_table_start__
ldr r5, =__copy_table_end__
.L_loop0:
cmp r4, r5
bge .L_loop0_done
ldr r1, [r4]
ldr r2, [r4, #4]
ldr r3, [r4, #8]
.L_loop0_0:
subs r3, #4
ittt ge
ldrge r0, [r1, r3]
strge r0, [r2, r3]
bge .L_loop0_0
adds r4, #12
b .L_loop0
.L_loop0_done:
#else
/* Single section scheme.
*
* The ranges of copy from/to are specified by following symbols
* __etext: LMA of start of the section to copy from. Usually end of text
* __data_start__: VMA of start of the section to copy to
* __data_end__: VMA of end of the section to copy to
*
* All addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__etext
ldr r2, =__data_start__
ldr r3, =__data_end__
.L_loop1:
cmp r2, r3
ittt lt
ldrlt r0, [r1], #4
strlt r0, [r2], #4
blt .L_loop1
#endif /*__STARTUP_COPY_MULTIPLE */
/* This part of work usually is done in C library startup code. Otherwise,
* define this macro to enable it in this startup.
*
* There are two schemes too. One can clear multiple BSS sections. Another
* can only clear one section. The former is more size expensive than the
* latter.
*
* Define macro __STARTUP_CLEAR_BSS_MULTIPLE to choose the former.
* Otherwise efine macro __STARTUP_CLEAR_BSS to choose the later.
*/
#ifdef __STARTUP_CLEAR_BSS_MULTIPLE
/* Multiple sections scheme.
*
* Between symbol address __copy_table_start__ and __copy_table_end__,
* there are array of tuples specifying:
* offset 0: Start of a BSS section
* offset 4: Size of this BSS section. Must be multiply of 4
*/
ldr r3, =__zero_table_start__
ldr r4, =__zero_table_end__
.L_loop2:
cmp r3, r4
bge .L_loop2_done
ldr r1, [r3]
ldr r2, [r3, #4]
movs r0, 0
.L_loop2_0:
subs r2, #4
itt ge
strge r0, [r1, r2]
bge .L_loop2_0
adds r3, #8
b .L_loop2
.L_loop2_done:
#elif defined (__STARTUP_CLEAR_BSS)
/* Single BSS section scheme.
*
* The BSS section is specified by following symbols
* __bss_start__: start of the BSS section.
* __bss_end__: end of the BSS section.
*
* Both addresses must be aligned to 4 bytes boundary.
*/
ldr r1, =__bss_start__
ldr r2, =__bss_end__
movs r0, 0
.L_loop3:
cmp r1, r2
itt lt
strlt r0, [r1], #4
blt .L_loop3
#endif /* __STARTUP_CLEAR_BSS_MULTIPLE || __STARTUP_CLEAR_BSS */
#ifndef __NO_SYSTEM_INIT
bl SystemInit
#endif
#ifndef __START
#define __START _start
#endif
bl __START
.pool
.size Reset_Handler, . - Reset_Handler
.align 1
.thumb_func
.weak Default_Handler
.type Default_Handler, %function
Default_Handler:
b .
.size Default_Handler, . - Default_Handler
/* Macro to define default handlers. Default handler
* will be weak symbol and just dead loops. They can be
* overwritten by other handlers */
.macro def_irq_handler handler_name
.weak \handler_name
.set \handler_name, Default_Handler
.endm
def_irq_handler NMI_Handler
def_irq_handler HardFault_Handler
def_irq_handler MemManage_Handler
def_irq_handler BusFault_Handler
def_irq_handler UsageFault_Handler
def_irq_handler SVC_Handler
def_irq_handler DebugMon_Handler
def_irq_handler PendSV_Handler
def_irq_handler SysTick_Handler
/* Interrupt Handlers */
def_irq_handler WWDG_IRQHandler
def_irq_handler I2C0_IRQHandler
def_irq_handler I2C1_IRQHandler
def_irq_handler TIM0_IRQHandler
def_irq_handler TIM1_IRQHandler
def_irq_handler TIM2_IRQHandler
def_irq_handler DMA_Stream0_IRQHandler
def_irq_handler DMA_Stream1_IRQHandler
def_irq_handler DMA_Stream2_IRQHandler
def_irq_handler DMA_Stream3_IRQHandler
def_irq_handler DMA_Stream4_IRQHandler
def_irq_handler DMA_Stream5_IRQHandler
def_irq_handler DMA_Stream6_IRQHandler
def_irq_handler DMA_Stream7_IRQHandler
def_irq_handler DMA_Stream8_IRQHandler
def_irq_handler DMA_Stream9_IRQHandler
def_irq_handler DMA_Stream10_IRQHandler
def_irq_handler DMA_Stream11_IRQHandler
def_irq_handler DMA_Stream12_IRQHandler
def_irq_handler DMA_Stream13_IRQHandler
def_irq_handler DMA_Stream14_IRQHandler
def_irq_handler DMA_Stream15_IRQHandler
def_irq_handler DMA_Stream16_IRQHandler
def_irq_handler DMA_Stream17_IRQHandler
def_irq_handler DMA_Stream18_IRQHandler
def_irq_handler DMA_Stream19_IRQHandler
def_irq_handler DMA_Stream20_IRQHandler
def_irq_handler DMA_Stream21_IRQHandler
def_irq_handler DMA_Stream22_IRQHandler
def_irq_handler DMA_Stream23_IRQHandler
def_irq_handler UART0_MX_IRQHandler
def_irq_handler UART0_RX_IRQHandler
def_irq_handler UART0_TX_IRQHandler
def_irq_handler UART0_RT_IRQHandler
def_irq_handler UART0_E_IRQHandler
def_irq_handler UART0_IRQHandler
def_irq_handler UART1_MX_IRQHandler
def_irq_handler UART1_RX_IRQHandler
def_irq_handler UART1_TX_IRQHandler
def_irq_handler UART1_RT_IRQHandler
def_irq_handler UART1_E_IRQHandler
def_irq_handler UART1_IRQHandler
def_irq_handler UART2_MX_IRQHandler
def_irq_handler UART2_RX_IRQHandler
def_irq_handler UART2_TX_IRQHandler
def_irq_handler UART2_RT_IRQHandler
def_irq_handler UART2_E_IRQHandler
def_irq_handler UART2_IRQHandler
def_irq_handler UART3_MX_IRQHandler
def_irq_handler UART3_RX_IRQHandler
def_irq_handler UART3_TX_IRQHandler
def_irq_handler UART3_RT_IRQHandler
def_irq_handler UART3_E_IRQHandler
def_irq_handler UART3_IRQHandler
def_irq_handler PWM0_IRQHandler
def_irq_handler PWM0_HD_IRQHandler
def_irq_handler PWM0_TZ_IRQHandler
def_irq_handler PWM1_IRQHandler
def_irq_handler PWM1_HD_IRQHandler
def_irq_handler PWM1_TZ_IRQHandler
def_irq_handler PWM2_IRQHandler
def_irq_handler PWM2_HD_IRQHandler
def_irq_handler PWM2_TZ_IRQHandler
def_irq_handler PWM3_IRQHandler
def_irq_handler PWM3_HD_IRQHandler
def_irq_handler PWM3_TZ_IRQHandler
def_irq_handler PWM4_IRQHandler
def_irq_handler PWM4_HD_IRQHandler
def_irq_handler PWM4_TZ_IRQHandler
def_irq_handler PWM5_IRQHandler
def_irq_handler PWM5_HD_IRQHandler
def_irq_handler PWM5_TZ_IRQHandler
def_irq_handler PWM6_IRQHandler
def_irq_handler PWM6_HD_IRQHandler
def_irq_handler PWM6_TZ_IRQHandler
def_irq_handler PWM7_IRQHandler
def_irq_handler PWM7_HD_IRQHandler
def_irq_handler PWM7_TZ_IRQHandler
def_irq_handler PWM8_IRQHandler
def_irq_handler PWM8_HD_IRQHandler
def_irq_handler PWM8_TZ_IRQHandler
def_irq_handler ADC_SEQ0_IRQHandler
def_irq_handler ADC_SEQ1_IRQHandler
def_irq_handler ADC_SEQ2_IRQHandler
def_irq_handler ADC_SEQ3_IRQHandler
def_irq_handler ADC_SEQ4_IRQHandler
def_irq_handler ADC_SEQ5_IRQHandler
def_irq_handler ADC_SEQ6_IRQHandler
def_irq_handler ADC_SEQ7_IRQHandler
def_irq_handler ADC_CompInt_IRQHandler
def_irq_handler CAP0_IRQHandler
def_irq_handler CAP1_IRQHandler
def_irq_handler CAP2_IRQHandler
def_irq_handler CAP3_IRQHandler
def_irq_handler CAP4_IRQHandler
def_irq_handler CAP5_IRQHandler
def_irq_handler QEP0_IRQHandler
def_irq_handler QEP1_IRQHandler
def_irq_handler BootFlash_IRQHandler
def_irq_handler CMP0_IRQHandler
def_irq_handler CMP1_IRQHandler
def_irq_handler CMP2_IRQHandler
def_irq_handler SPI0_IRQHandler
def_irq_handler SPI1_IRQHandler
def_irq_handler SPI2_IRQHandler
def_irq_handler SPI3_IRQHandler
def_irq_handler UserFlash_IRQHandler
def_irq_handler GPIOA_IRQHandler
def_irq_handler GPIOB_IRQHandler
def_irq_handler GPIOC_IRQHandler
def_irq_handler GPIOD_IRQHandler
def_irq_handler GPIOE_IRQHandler
def_irq_handler GPIOF_IRQHandler
def_irq_handler GPIOG_IRQHandler
def_irq_handler GPIOH_IRQHandler
def_irq_handler Ethernet_IRQHandler
def_irq_handler CAN0_IRQHandler
def_irq_handler CAN1_IRQHandler
def_irq_handler CAN2_IRQHandler
def_irq_handler CAN3_IRQHandler
def_irq_handler CAN4_IRQHandler
def_irq_handler CAN5_IRQHandler
def_irq_handler CAN6_IRQHandler
def_irq_handler CAN7_IRQHandler
def_irq_handler CAN8_IRQHandler
def_irq_handler CAN9_IRQHandler
def_irq_handler CAN10_IRQHandler
def_irq_handler CAN11_IRQHandler
def_irq_handler CAN12_IRQHandler
def_irq_handler CAN13_IRQHandler
def_irq_handler CAN14_IRQHandler
def_irq_handler CAN15_IRQHandler
def_irq_handler RTC_IRQHandler
def_irq_handler USB_IRQHandler
.end
/**
******************************************************************************
* @file main.c
*
* @brief Пример выполнения операций с основной загрузочной флеш: чтение,
* запись, стирание.
*
* Текущий контроллер не поддерживает работу с внутренней памятью из
* внутренней памяти, поэтому происходит переход в функцию,
* расположенную в ОЗУ, откуда и вызываются функции драйвера для
* записи и стирания.
*
* В примере читаются и выводятся в терминал последовательно 4
* 32-разрядных слова. Затем происходит запись новых данных.
* Обновленные данные считываются, а затем происходит стирание
* страницы с модифицированными адресами.
*
* При компиляции будет выдаваться предупреждение:
* Warning: setting incorrect section attributes for .data.ramfunc
* Оно связано с примененным методом расположения функции в ОЗУ и его
* следует проигнорировать.
*
* Для того чтобы функция из ОЗУ корректно вызывалась, компилятору был
* дополнительно передан ключ -mlong-calls.
*
* Компилятор: GCC ARM 4.9.3
* Среда: Qt Creator 3.4.2
*
* @author НИИЭТ
* - Богдан Колбов (bkolbov), kolbov@niiet.ru
* @date 07.12.2015
*
******************************************************************************
* @attention
*
* ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО
* ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ
* ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ
* НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
* ПРЕДНАЗНАЧЕНО ДЛЯ ОЗНАКОМИТЕЛЬНЫХ ЦЕЛЕЙ И НАПРАВЛЕНО ТОЛЬКО НА
* ПРЕДОСТАВЛЕНИЕ ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ О ПРОДУКТЕ, С ЦЕЛЬЮ СОХРАНИТЬ ВРЕМЯ
* ПОТРЕБИТЕЛЮ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ
* ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА ПРЯМОЙ ИЛИ КОСВЕННЫЙ УЩЕРБ, ИЛИ
* ПО ИНЫМ ТРЕБОВАНИЯМ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
* ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
*
* <h2><center>&copy; 2015 ОАО "НИИЭТ"</center></h2>
******************************************************************************
*/
#include "niietcm4.h"
#include "retarget.h"
#define RAMFUNC __attribute__((long_call, section(".data.ramfunc")))
void SystemInit()
{
// инициализация printf
retarget_init();
BOOTFLASH_Init(EXT_OSC_VALUE);
}
uint32_t read_arr[4] = {0x11111111, 0x22222222, 0x33333333, 0x44444444};
RAMFUNC void ram_main()
{
uint32_t addr = 0x00003010;
// читаем значения до всех операций
printf("Read flash before operation:\n");
for (uint32_t i = 0; i < 4; i++)
{
printf("%d - 0x%x - 0x%x\n", i, addr + 0x4*i, *(volatile uint32_t*)(addr + 0x4*i));
}
// пишем значения
printf("Performing write...\n");
BOOTFLASH_Write(addr, 0xDEADF00D, 0xCAFEBABE, 0xBEEFBEEF, 0x79977997);
// ждем выполнения
while(BOOTFLASH_OperationStatus() != BOOTFLASH_Status_Complete);
BOOTFLASH_OperationStatusClear();
// читаем и выводим новые значения
printf("Write operation complete!\n");
printf("Current values:\n");
for (uint32_t i = 0; i < 4; i++)
{
printf("%d - 0x%x - 0x%x\n", i, addr + 0x4*i, *(volatile uint32_t*)(addr + 0x4*i));
}
// стираем страницу, куда писали
printf("Performing page erase...\n");
BOOTFLASH_PageErase(addr/BOOTFLASH_PAGE_SIZE_BYTES);
// ждем выполнения
while(BOOTFLASH_OperationStatus() != BOOTFLASH_Status_Complete);
BOOTFLASH_OperationStatusClear();
// читаем и выводим новые значения
printf("Erase operation complete!\n");
printf("Current values:\n");
for (uint32_t i = 0; i < 4; i++)
{
printf("%d - 0x%x - 0x%x\n", i, addr + 0x4*i, *(volatile uint32_t*)(addr + 0x4*i));
}
}
int main()
{
// Чтобы выполнять операции над флешкой, нужно перейти в ОЗУ.
// Однако, прямой вызов функции не сработает, т.к. функция будет за пределами видимости
// поэтому использован такой костыль.
static void (*pramfunc)(void) = ram_main;
(*pramfunc)();
printf("The end!\n");
while(1);
}
/**
******************************************************************************
* @file retarget.c
*
* @brief Содержит реализацию функции инициализации UART, а также
* переопределенные библиотечные функции, относящиеся к printf.
* Также стоить обратить внимание, что для того чтобы все работало,
* в компилятор необходимо передаеть ключ -fno-builtin,
* а линкеру --specs=nosys.specs
*
* Компилятор: GCC ARM 4.9.3
* Среда: Qt Creator 3.4.2
*
* @author НИИЭТ
* - Богдан Колбов (bkolbov), kolbov@niiet.ru
* @date 02.12.2015
*
******************************************************************************
* @attention
*
* ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО
* ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ
* ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ
* НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
* ПРЕДНАЗНАЧЕНО ДЛЯ ОЗНАКОМИТЕЛЬНЫХ ЦЕЛЕЙ И НАПРАВЛЕНО ТОЛЬКО НА
* ПРЕДОСТАВЛЕНИЕ ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ О ПРОДУКТЕ, С ЦЕЛЬЮ СОХРАНИТЬ ВРЕМЯ
* ПОТРЕБИТЕЛЮ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ
* ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА ПРЯМОЙ ИЛИ КОСВЕННЫЙ УЩЕРБ, ИЛИ
* ПО ИНЫМ ТРЕБОВАНИЯМ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
* ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
*
* <h2><center>&copy; 2015 ОАО "НИИЭТ"</center></h2>
******************************************************************************
*/
#include "retarget.h"
void retarget_init()
{
GPIO_Init_TypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct);
// настройка портов и снятие сброса
if (RETARGET_UART == NT_UART0)
{
// хак, необходимый, чтобы была возможность использовать вывоводы со 2 функцией
GPIO_AltFuncConfig(NT_GPIOD, GPIO_Pin_11, GPIO_AltFunc_3); // uart0 tx
GPIO_AltFuncConfig(NT_GPIOE, GPIO_Pin_0, GPIO_AltFunc_3); // uart0 rx
// rx
GPIO_InitStruct.GPIO_AltFunc = GPIO_AltFunc_2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AltFunc;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(NT_GPIOC, &GPIO_InitStruct);
// tx
GPIO_InitStruct.GPIO_Dir = GPIO_Dir_Out;
GPIO_InitStruct.GPIO_Out = GPIO_Out_En;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(NT_GPIOC, &GPIO_InitStruct);
// снятие сброса
RCC_PeriphRstCmd(RCC_PeriphRst_UART0, ENABLE);
}
else if (RETARGET_UART == NT_UART1)
{
// rx
GPIO_InitStruct.GPIO_AltFunc = GPIO_AltFunc_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AltFunc;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4;
GPIO_Init(NT_GPIOA, &GPIO_InitStruct);
// tx
GPIO_InitStruct.GPIO_Dir = GPIO_Dir_Out;
GPIO_InitStruct.GPIO_Out = GPIO_Out_En;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(NT_GPIOA, &GPIO_InitStruct);
// снятие сброса
RCC_PeriphRstCmd(RCC_PeriphRst_UART1, ENABLE);
}
else if (RETARGET_UART == NT_UART2)
{
// rx
GPIO_InitStruct.GPIO_AltFunc = GPIO_AltFunc_1;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AltFunc;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(NT_GPIOF, &GPIO_InitStruct);
// tx
GPIO_InitStruct.GPIO_Dir = GPIO_Dir_Out;
GPIO_InitStruct.GPIO_Out = GPIO_Out_En;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(NT_GPIOF, &GPIO_InitStruct);
// снятие сброса
RCC_PeriphRstCmd(RCC_PeriphRst_UART2, ENABLE);
}
else if (RETARGET_UART == NT_UART3)
{
// хак, необходимый, чтобы была возможность использовать вывоводы со 2 функцией
GPIO_AltFuncConfig(NT_GPIOF, GPIO_Pin_12 | GPIO_Pin_13, GPIO_AltFunc_3); // uart3 tx rx
// rx
GPIO_InitStruct.GPIO_AltFunc = GPIO_AltFunc_2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AltFunc;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;
GPIO_Init(NT_GPIOD, &GPIO_InitStruct);
// tx
GPIO_InitStruct.GPIO_Dir = GPIO_Dir_Out;
GPIO_InitStruct.GPIO_Out = GPIO_Out_En;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(NT_GPIOD, &GPIO_InitStruct);
// снятие сброса
RCC_PeriphRstCmd(RCC_PeriphRst_UART3, ENABLE);
}
// включение тактирования UART
RCC_UARTClkCmd(RETARGET_UART, ENABLE);
// настройка блоков UART
UART_Init_TypeDef UART_InitStruct;
UART_StructInit(&UART_InitStruct);
UART_InitStruct.UART_BaudRate = RETARGET_BAUDRATE_VAL;
UART_InitStruct.UART_ClkFreq = RETARGET_CLK_VAL;
UART_InitStruct.UART_DataWidth = UART_DataWidth_8;
UART_Init(RETARGET_UART, &UART_InitStruct);
UART_Cmd(RETARGET_UART, ENABLE);
// выделяем место под буффер
setvbuf(stdout, NULL, _IONBF, 0);
}
int _write (int fd, char *ptr, int len)
{
/* Write "len" of char from "ptr" to file id "fd"
* Return number of char written.
* Need implementing with UART here. */
int i = 0;
while (ptr[i] && (i < len))
{
while(UART_FlagStatus(RETARGET_UART, UART_Flag_Busy));
UART_SendData(RETARGET_UART, ptr[i]);
if (ptr[i] == '\n')
{
while(UART_FlagStatus(RETARGET_UART, UART_Flag_Busy));
UART_SendData(RETARGET_UART, '\r');
}
i++;
}
return len;
}
void _ttywrch(int ch)
{
/* Write one char "ch" to the default console
* Need implementing with UART here. */
while(UART_FlagStatus(RETARGET_UART, UART_Flag_Busy));
UART_SendData(RETARGET_UART, ch);
}
int _read(int file, char *ptr, int len)
{
return 0;
}
/**
******************************************************************************
* @file retarget.h
*
* @brief Содержит прототип функции инициализации UART для использования
* в качестве аппаратного интерфейса для printf.
*
* UART0 использует:
* - C[3] (TX)
* - C[4] (RX)
* UART1 использует:
* - A[3] (TX)
* - A[4] (RX)
* UART2 использует:
* - F[10] (TX)
* - F[11] (RX)
* UART3 использует:
* - D[2] (TX)
* - D[1] (RX)
*
* Компилятор: GCC ARM 4.9.3
* Среда: Qt Creator 3.4.2
*
* @author НИИЭТ
* - Богдан Колбов (bkolbov), kolbov@niiet.ru
* @date 02.12.2015
*
******************************************************************************
* @attention
*
* ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО
* ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ
* ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ
* НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ
* ПРЕДНАЗНАЧЕНО ДЛЯ ОЗНАКОМИТЕЛЬНЫХ ЦЕЛЕЙ И НАПРАВЛЕНО ТОЛЬКО НА
* ПРЕДОСТАВЛЕНИЕ ДОПОЛНИТЕЛЬНОЙ ИНФОРМАЦИИ О ПРОДУКТЕ, С ЦЕЛЬЮ СОХРАНИТЬ ВРЕМЯ
* ПОТРЕБИТЕЛЮ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ
* ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА ПРЯМОЙ ИЛИ КОСВЕННЫЙ УЩЕРБ, ИЛИ
* ПО ИНЫМ ТРЕБОВАНИЯМ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
* ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
*
* <h2><center>&copy; 2015 ОАО "НИИЭТ"</center></h2>
******************************************************************************
*/
#include "niietcm4.h"
#include <stdio.h>
// выбор UART для вывода printf
#define RETARGET_UART NT_UART2
// текущая системная частота в Гц
#define RETARGET_CLK_VAL EXT_OSC_VALUE
// желаемая скорость передачи
#define RETARGET_BAUDRATE_VAL 115200
// функция инициализации необходимого UART - настраивает сброс, тактирование,
// порты ввода-вывода и непосредственно сам блок UART
void retarget_init();
import qbs
import qbs.FileInfo
Product {
type: ["application", "hex", "bin", "size", "cp_hex" ]
Depends { name:"cpp" }
property string target: "K1921VK01T"
property string periph_driver: "../../../../../../periph_driver_lib/"
cpp.debugInformation: true
cpp.defines: [
"__STARTUP_CLEAR_BSS",
"__START=main",
target,
"EXT_OSC_VALUE=((uint32_t)16000000)"
]
cpp.optimization: "small"
cpp.cxxFlags: [
"-std=c++11"
]
cpp.cFlags: [
"-std=gnu99"
]
cpp.warningLevel: "all"
cpp.commonCompilerFlags: [
"-mthumb",
"-mcpu=cortex-m4",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"-fdata-sections",
"-ffunction-sections",
"-fno-builtin",
"-flto",
"-mlong-calls"
]
cpp.positionIndependentCode: false
cpp.executableSuffix: ".elf"
cpp.linkerScripts: [
"ldscripts/" + target + ".ld",
]
cpp.linkerFlags:[
"-mthumb",
"-mcpu=cortex-m4",
"-mfloat-abi=hard",
"-mfpu=fpv4-sp-d16",
"--specs=nano.specs",
"--specs=nosys.specs",
"-Wl,--gc-sections",
"-lgcc","-lc",
]
cpp.includePaths: [
"libs/CMSIS/Include/",
"libs/Device/",
periph_driver + "inc/"
]
Group {
name: "Application"
prefix: "./"
files: [
"*.c",
"*.cpp",
"*.h",
"*.s"
]
}
Group {
name: "CMSIS"
prefix: "libs/CMSIS/**/"
files: [
"*.c",
"*.cpp",
"*.h",
"*.s"
]
}
Group {
name: "Device"
prefix: "libs/Device/**/"
files: [
"*.c",
"*.cpp",
"*.h",
"*.s"
]
}
Group {
name: "Peripheral Driver"
prefix: periph_driver + "/**/"
files: [
"*.c",
"*.cpp",
"*.h",
"*.s"
]
}
Group {
name: "Linker Scripts"
prefix: "ldscripts/**/"
files: "*.ld"
}
Rule {
id: hex
inputs: "application"
Artifact {
fileTags: ["hex"]
filePath: FileInfo.baseName(input.filePath) + ".hex"
}
prepare: {
var args = ["-O", "ihex", input.filePath, output.filePath];
var cmd = new Command("arm-none-eabi-objcopy", args);
cmd.description = "converting to hex: "+FileInfo.fileName(input.filePath);
cmd.highlight = "linker";
return cmd;
}
}
Rule {
id: bin
inputs: "application"
Artifact {
fileTags: ["bin"]
filePath: FileInfo.baseName(input.filePath) + ".bin"
}
prepare: {
var args = ["-O", "binary", input.filePath, output.filePath];
var cmd = new Command("arm-none-eabi-objcopy", args);
cmd.description = "converting to bin: "+FileInfo.fileName(input.filePath);
cmd.highlight = "linker";
return cmd;
}
}
Rule {
id: size
inputs: ["application"]
Artifact {
fileTags: ["size"]
filePath: "-"
}
prepare: {
var args = [input.filePath];
var cmd = new Command("arm-none-eabi-size", args);
cmd.description = "File size: " + FileInfo.fileName(input.filePath);
cmd.highlight = "linker";
return cmd;
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment