Special function types can be used for static member functions. For example, in the
The following example is the interrupt function:
class Device { static __irq void handler(); };
On the ARM Cortex-M, an interrupt service line
normal function, which means no special keywords are required. Thus, the keywords
__irq, __fiq, and __nested are not available when you compile for ARM Cortex-M.
These exception function names are defined in cstartup_M.c and cstartup_M.s.
Vector code:
NMI_Handler
HardFault_Handler
MemManage_Handler
BusFault_Handler
...
The vector table is implemented as an array. It should always have the name
__vector_table
#pragma language = extended #pragma segment = "CSTACK" extern "C" void __iar_program_start( void ); extern "C" void vPortSVCHandler(void); extern "C" void xPortPendSVHandler(void); extern "C" void xPortSysTickHandler(void); class cNMI { public: static void handler(void); }; class cHardFault { public: static void handler(void); }; class cMemManage { public: static void handler(void); }; class cBusFault { public: static void handler(void); }; class cUsageFault { public: static void handler(void); }; class cDebugMon { public: static void handler(void); }; class cWindowWatchdog { public: static void handler(void); }; class cPvd { public: static void handler(void); }; class cTamperTimeStamp { public: static void handler(void); }; class cRtcWakeup { public: static void handler(void); }; class cFlash { public: static void handler(void); }; class cRcc { public: static void handler(void); }; class cExti { public: static void line0Handler(void); static void line1Handler(void); static void line2Handler(void); static void line3Handler(void); static void line4Handler(void); static void line9Handler(void); static void line15_10Handler(void); }; class cDma { public: static void channellHandler(void); static void channel2Handler(void); static void channel3Handler(void); static void channel4Handler(void); static void channel5Handler(void); static void channel6Handler(void); static void channel7Handler(void); }; class cAdc { public: static void handler(void); }; class cDac { public: static void handler(void); }; class cUsb { public: static void highPriorityHandler(void); static void lowPriorityHandler(void); static void fsWakeupHandler(void); }; class cComp { public: static void handler(void); }; class cLcdDriver { public: static void handler(void); }; class cTim9 { public: static void handler(void); }; class cTim2 { public: static void handler(void); }; class cTim3 { public: static void handler(void); }; class cTim4 { public: static void handler(void); }; class cTim10 { public: static void handler(void); }; class cTim6 { public: static void handler(void); }; class cTim7 { public: static void handler(void); }; class cTim11 { public: static void handler(void); }; class cI2C1 { public: static void eventHandler(void); static void errorHandler(void); }; class cI2C2 { public: static void eventHandler(void); static void errorHandler(void); }; class cSpi1 { public: static void handler(void); }; class cSpi2 { public: static void handler(void); }; class cUart1 { public: static void handler(void); }; class cUart2 { public: static void handler(void); }; class cUart3 { public: static void handler(void); }; class cRtcAlarm { public: static void handler(void); }; typedef void( *intfunc )( void ); typedef union { intfunc __fun; void * __ptr; } intvec_elem; // The vector table is normally located at address 0. // When debugging in RAM, it can be located in RAM, aligned to at least 2^6. // If you need to define interrupt service routines, // make a copy of this file and include it in your project. // The name "__vector_table" has special meaning for C-SPY: // it is where the SP start value is found, and the NVIC vector // table register (VTOR) is initialized to this address if != 0. #pragma location = ".intvec" extern "C" const intvec_elem __vector_table[] = { { .__ptr = __sfe( "CSTACK" ) }, __iar_program_start, cNMI::handler, cHardFault::handler, cMemManage::handler, cBusFault::handler, cUsageFault::handler, 0, 0, 0, 0, vPortSVCHandler, // freeRTOS ! cDebugMon::handler, 0, xPortPendSVHandler, // freeRTOS ! xPortSysTickHandler, // freeRTOS ! //External Interrupts cWindowWatchdog::handler, //Window Watchdog cPvd::handler, //PVD through EXTI Line detect cTamperTimeStamp::handler, //Tamper and Time Stamp cRtcWakeup::handler, //RTC Wakeup cFlash::handler, //FLASH cRcc::handler, //RCC cExti::line0Handler, //EXTI Line 0 cExti::line1Handler, //EXTI Line 1 cExti::line2Handler, //EXTI Line 2 cExti::line3Handler, //EXTI Line 3 cExti::line4Handler, //EXTI Line 4 cDma::channellHandler, //DMA1 Channel 1 cDma::channel2Handler, //DMA1 Channel 2 cDma::channel3Handler, //DMA1 Channel 3 cDma::channel4Handler, //DMA1 Channel 4 cDma::channel5Handler, //DMA1 Channel 5 cDma::channel6Handler, //DMA1 Channel 6 cDma::channel7Handler, //DMA1 Channel 7 cAdc::handler, //ADC1 cUsb::highPriorityHandler, //USB High Priority cUsb::lowPriorityHandler, //USB Low Priority cDac::handler, //DAC cComp::handler, //COMP through EXTI Line cExti::line9Handler, //EXTI Line 9..5 cLcdDriver::handler, //LCD cTim9::handler, //TIM9 cTim10::handler, //TIM10 cTim11::handler, //TIM11 cTim2::handler, //TIM2 cTim3::handler, //TIM3 cTim4::handler, //TIM4 cI2C1::eventHandler, //I2C1 Event cI2C1::errorHandler, //I2C1 Error cI2C2::eventHandler, //I2C2 Event cI2C2::errorHandler, //I2C2 Error cSpi1::handler, //SPI1 cSpi2::handler, //SPI2 cUart1::handler, //USART1 cUart2::handler, //USART2 cUart3::handler, //USART3 cExti::line15_10Handler, //EXTI Line 15..10 cRtcAlarm::handler, //RTC Alarm through EXTI Line cUsb::fsWakeupHandler, //USB FS Wakeup from suspend cTim6::handler, //TIM6 cTim7::handler //TIM7 }; __weak void cNMI::handler() { while (1) {} } __weak void cHardFault::handler() { while (1) {} } __weak void cMemManage::handler() { while (1) {} } __weak void cBusFault::handler() { while (1) {} } __weak void cUsageFault::handler() { while (1) {} } __weak void cDebugMon::handler() { while (1) {} } __weak void cWindowWatchdog::handler() { while (1) {} } __weak void cPvd::handler() { while (1) {} } __weak void cTamperTimeStamp::handler() { while (1) {} } __weak void cRtcWakeup::handler() { while (1) {} } __weak void cFlash::handler() { while (1) {} } __weak void cRcc::handler() { while (1) {} } __weak void cExti::line0Handler() { while (1) {} } __weak void cExti::line1Handler() { while (1) {} } __weak void cExti::line2Handler() { while (1) {} } __weak void cExti::line3Handler() { while (1) {} } __weak void cExti::line4Handler() { while (1) {} } __weak void cExti::line9Handler() { while (1) {} } __weak void cExti::line15_10Handler() { while (1) {} } __weak void cDma::channellHandler() { while (1) {} } __weak void cDma::channel2Handler() { while (1) {} } __weak void cDma::channel3Handler() { while (1) {} } __weak void cDma::channel4Handler() { while (1) {} } __weak void cDma::channel5Handler() { while (1) {} } __weak void cDma::channel6Handler() { while (1) {} } __weak void cDma::channel7Handler() { while (1) {} } __weak void cAdc::handler() { while (1) {} } __weak void cUsb::fsWakeupHandler() { while (1) {} } __weak void cUsb::highPriorityHandler() { while (1) {} } __weak void cUsb::lowPriorityHandler() { while (1) {} } __weak void cDac::handler() { while (1) {} } __weak void cComp::handler() { while (1) {} } __weak void cLcdDriver::handler() { while (1) {} } __weak void cTim2::handler() { while (1) {} } __weak void cTim3::handler() { while (1) {} } __weak void cTim4::handler() { while (1) {} } __weak void cTim6::handler() { while (1) {} } __weak void cTim7::handler() { while (1) {} } __weak void cTim9::handler() { while (1) {} } __weak void cTim10::handler() { while (1) {} } __weak void cTim11::handler() { while (1) {} } __weak void cI2C1::errorHandler() { while (1) {} } __weak void cI2C1::eventHandler() { while (1) {} } __weak void cI2C2::errorHandler() { while (1) {} } __weak void cI2C2::eventHandler() { while (1) {} } __weak void cSpi1::handler() { while (1) {} } __weak void cSpi2::handler() { while (1) {} } __weak void cUart1::handler() { while (1) {} } __weak void cUart2::handler() { while (1) {} } __weak void cUart3::handler() { while (1) {} } __weak void cRtcAlarm::handler() { while (1) {} } extern "C" void __cmain( void ); extern "C" __weak void __iar_init_core( void ); extern "C" __weak void __iar_init_vfp( void ); #pragma required=__vector_table void __iar_program_start( void ) { __iar_init_core(); __iar_init_vfp(); __cmain(); }
Command1.Response.PrimaryVariable = 3.54 Command1.Send();
#include "susutypes.h" #include "observable.h" class cLinkLayerTimer : public iObservable { public: explicit cLinkLayerTimer(tU16 timeout); void start(void) const; private: static void irqHandler(void); static cLinkLayerTimer* instance; };
#include "linklayertimer.h" #include "susuassert.h" #include <stdio.h> cLinkLayerTimer* cLinkLayerTimer::instance = NULL; /******************************************************************************* * Function: constructor * Description: TIM2 ******************************************************************************/ cLinkLayerTimer::cLinkLayerTimer(tU16 timeout) { ASSERT(instance != NULL); this->instance = this; TIM2->ARR = (uint16_t)timeout; } /******************************************************************************* * Function: start * Description: . ******************************************************************************/ void cLinkLayerTimer::start(void) const { TIM2->CNT = (uint16_t)0; TIM2->CR1 |= TIM_CR1_CEN; } /******************************************************************************* * Function: irqHandler * Description: . * , ******************************************************************************/ void cLinkLayerTimer::irqHandler(void) { ASSERT(instance != NULL); instance->notifyObservers(); TIM2->CR1 &=~ TIM_CR1_CEN; TIM2->SR &= ~TIM_SR_UIF; }
#include "susutypes.h" #include "linklayertimer.h" #include "observer.h" #define PREAMBUL_SYMBOL (uint16_t) 0xFF typedef enum { LLS_none = 0, LLS_write = 1, LLS_writeComplete = 2, LLS_readComplete = 3, LLS_error = 4 } tLinkLayerStatus; class cLinkLayer : private iObserver, public iObservable { public: explicit cLinkLayer(tU8 *pRxBuf, const tU8 rxBufSize,tU8 *pTxBuf, const tU8 preambulCount); void writeData(tU8 dataSize); tLinkLayerStatus getStatus() const { return eStatus; }; virtual void eventHandle(const iObservable* pObservable); tU8* pTxBuffer; tU8* pRxBuffer; private: static void irqHandler(void); static cLinkLayer* instance; void endMessageHandler(void); void enableReceive(void) const { USART2->CR1 |= USART_CR1_RXNEIE;}; void disableReceive(void){USART2->CR1 &=~ USART_CR1_RXNEIE;}; void enableTransmit(void) const { USART2->CR1 |= USART_CR1_TCIE; }; void disableTransmit(void) const { USART2->CR1 &=~ USART_CR1_TCIE; }; tLinkLayerStatus eStatus; cLinkLayerTimer* pEndTransmitTimer; tU8 rxBufferSize; tU8 rxBufferIndex; tU8 txBufferIndex; tU8 txBufferSize; tU8 preambulsCount; tU8 preambulIndex; tBoolean readPreambuls; };
#include <stm32l1xx.h> #include "linklayer.h" #include "susuassert.h" #include <stdio.h> #define END_MESSAGE_TIMEOUT (tU16) 19 #define GOOD_COUNT_RX_PREAMBULS (tU8) 2 cLinkLayer* cLinkLayer::instance = NULL; /******************************************************************************* * Function: constructor * Description: ******************************************************************************/ cLinkLayer::cLinkLayer(tU8 *pRxBuf, const tU8 rxBufSize,tU8 *pTxBuf, const tU8 preambulCount) { ASSERT (rxBuffer != NULL); ASSERT (txBuffer != NULL); // 3 ASSERT(preambulCount > (tU8)2); this->preambulsCount = preambulCount; this->preambulIndex = (tU8)0; this->readPreambuls = TRUE; this->pRxBuffer = pRxBuf; this->rxBufferSize = rxBufSize; this->rxBufferIndex = (tU8)0; this->pTxBuffer = pTxBuf; this->txBufferSize = (tU8)0; this->txBufferIndex = (tU8)0; this->eStatus = LLS_none; this->instance = this; this->pEndTransmitTimer = new cLinkLayerTimer(END_MESSAGE_TIMEOUT); // this->pEndTransmitTimer->addObserver(this); this->disableTransmit(); this->enableReceive(); } /******************************************************************************* * Function: writeData * Description: , ******************************************************************************/ void cLinkLayer::writeData(tU8 dataSize) { // , , // if (this->eStatus != LLS_write) { this->disableReceive(); this->txBufferSize = dataSize; this->eStatus = LLS_write; USART2->DR = PREAMBUL_SYMBOL; this->preambulIndex ++; this->enableTransmit(); } } /******************************************************************************* * Function: handler * Description: ******************************************************************************/ void cLinkLayer::irqHandler(void) { ASSERT(instance != NULL); // if (USART2->SR & USART_SR_TC) { // , 3 if (instance->preambulIndex != instance->preambulsCount) { USART2->DR = PREAMBUL_SYMBOL; instance->preambulIndex ++; } else { // - if(instance->txBufferIndex < instance->txBufferSize) { USART2->DR = (uint16_t)instance->pTxBuffer[instance->txBufferIndex++]; } else { instance->txBufferIndex = (tU8)0; instance->txBufferSize = (tU8)0; instance->disableTransmit(); instance->eStatus = LLS_writeComplete; instance->preambulIndex = (tU8)0; instance->readPreambuls = TRUE; instance->enableReceive(); } } USART2->SR &=~ USART_SR_TC; }; // if (USART2->SR & USART_SR_RXNE) { instance->pRxBuffer[instance->rxBufferIndex] = (tU8)USART2->DR; instance->pEndTransmitTimer->start(); // if (instance->readPreambuls) { if (instance->pRxBuffer[instance->rxBufferIndex] == (tU8)PREAMBUL_SYMBOL) { instance->preambulIndex++; } else { instance->readPreambuls = FALSE; instance->rxBufferIndex++; } } else { // 2 if ((instance->rxBufferIndex <= instance->rxBufferSize) && (instance->preambulIndex >= GOOD_COUNT_RX_PREAMBULS)) { instance->rxBufferIndex++; } else { instance->eStatus = LLS_error; instance->preambulIndex = (tU8)0; } } } } /******************************************************************************* * Function: endMessageHandler * Description: ******************************************************************************/ void cLinkLayer::endMessageHandler(void) { this->eStatus = LLS_readComplete; this->rxBufferIndex = (tU8) 0; this->readPreambuls = TRUE; instance->preambulIndex = (tU8)0; } /******************************************************************************* * Function: eventHandle * Description: ******************************************************************************/ void cLinkLayer::eventHandle(const iObservable* pObservable) { this->endMessageHandler(); this->notifyObservers(); }
Command0.Response.PrimaryVariable = 3.54
void cCommand1::setNewData(void) { // this->pResponse = (tCommand1Response*) this->pFrame->buildFrameBeforeData(COMMAND1, (tU8)sizeof(tCommand1Response)); this->pResponse->status1 = (tU8)0; this->pResponse->status2 = (tU8)0; this->pResponse->PrimaryVariableUnits = (tU8) pVariables->pTrimmer->getUnits(); this->pResponse->PrimaryVariableValue = std::swap<tF32>(pVariables->pTrimmer->getValue()); this->pFrame->setCheckSumm(); }
class iBaseDwartCommand { public: virtual void send(void) = 0; virtual void setNewData(void) = 0; };
#include "frame.h" #include "basecommand.h" #include "susuassert.h" template <class req, class resp> class iDwartCommand : public iBaseDwartCommand { public: explicit iDwartCommand(cFrame *pDwratFrame); req *pRequest; resp *pResponse; void send(void); protected: cFrame *pFrame; }; /******************************************************************************* * Function: constructor * Description: ******************************************************************************/ template <class req, class resp> iDwartCommand<req, resp>::iDwartCommand(cFrame *pDwartFrame) { ASSERT (pFrame != NULL); this->pFrame = pDwartFrame; } /******************************************************************************* * Function: send * Description: ******************************************************************************/ template <class req, class resp> void iDwartCommand<req, resp>::send(void) { this->pFrame->send(); }
#include "command.h" #define COMMAND0 (tU8)0 #pragma pack(push, 1) typedef struct { tU8 status1; tU8 status2; tU8 expansion; tU8 manufacturer; tU8 deviceType; tU8 numberOfpreambuls; tU8 universalCommandRevision; tU8 deviceSpecificCommandRevision; tU8 softwareRevision; tU8 hardwareRevision; tU8 deviceFlags; tU8 deviceID[3]; } tCommand0Response; typedef struct { } tCommand0Request; #pragma pack(pop) class cCommand0: public iDwartCommand<tCommand0Request, tCommand0Response> { public: explicit cCommand0(cFrame *pDwartFrame); virtual void setNewData(void); };
include "susuassert.h" #include "command0.h" #include "frame.h" /******************************************************************************* * Function: constructor * Description: ******************************************************************************/ cCommand0::cCommand0(cFrame *pDwartFrame): iDwartCommand(pDwartFrame) { } /******************************************************************************* * Function: setNewData * Description: ******************************************************************************/ void cCommand0::setNewData(void) { // this->pResponse = (tCommand0Response*) this->pFrame->buildFrameBeforeData(COMMAND0, (tU8)sizeof(tCommand0Response)); this->pResponse->status1 = (tU8)0; this->pResponse->status2 = (tU8)0; this->pResponse->manufacturer = (tU8)0x37; this->pResponse->deviceType = (tU8)0x04; this->pResponse->expansion = (tU8)0; this->pResponse->deviceSpecificCommandRevision = (tU8)5; this->pResponse->universalCommandRevision = (tU8)5; this->pResponse->hardwareRevision = (tU8)1; this->pResponse->softwareRevision = (tU8)201; this->pResponse->numberOfpreambuls = (tU8)5; this->pResponse->deviceID[0] = (tU8)0; this->pResponse->deviceID[1] = (tU8)0; this->pResponse->deviceID[2] = (tU8)1; this->pResponse->deviceFlags = (tU8)0; this->pFrame->setCheckSumm(); }
#include "command.h" #include "vars.h" #define COMMAND1 (tU8)1 #pragma pack(push, 1) typedef struct { tU8 status1; tU8 status2; tU8 PrimaryVariableUnits; tF32 PrimaryVariableValue; } tCommand1Response; typedef struct { } tCommand1Request; #pragma pack(pop) class cCommand1: public iDwartCommand<tCommand1Request, tCommand1Response> { public: explicit cCommand1(cFrame *pDwartFrame,Variablesr *Vars); virtual void setNewData(void); private: Variables *pVariables; };
#include "susuassert.h" #include "command1.h" #include "frame.h" /******************************************************************************* * Function: constructor * Description: ******************************************************************************/ cCommand1::cCommand1(cFrame *pDwartFrame, Variables *pVars): iDwartCommand(pDwartFrame) { ASSERT(pVars != NULL); this->pVariables = pVars; } /******************************************************************************* * Function: setNewData * Description: ******************************************************************************/ void cCommand1::setNewData(void) { // this->pResponse = (tCommand1Response*) this->pFrame->buildFrameBeforeData(COMMAND1, (tU8)sizeof(tCommand1Response)); this->pResponse->status1 = (tU8)0; this->pResponse->status2 = (tU8)0; this->pResponse->PrimaryVariableUnits = (tU8) pVariables->pTrimmer->getUnits(); this->pResponse->PrimaryVariableValue = std::swap<tF32>(pVariables->pTrimmer->getValue()); this->pFrame->setCheckSumm(); }
#include "command.h" #include "variables.h" #define COMMANDS_COUNT 254 class cCommandSet { public: cCommandSet(cFrame *pFrame, Variables *pVariables); iBaseDwartCommand *pCommands[COMMANDS_COUNT]; };
#include "susuassert.h" #include "commandset.h" #include "command0.h" #include "command1.h" #include "command2.h" #include "command3.h" #include "command12.h" #include "command13.h" #include "command14.h" #include "command15.h" #include "command157.h" #include "command159.h" #include "command160.h" #include "command180.h" cCommandSet::cCommandSet(cFrame *pFrame, cVariables *pVariables) { this->pCommands[COMMAND0] = new cCommand0(pFrame); this->pCommands[COMMAND1] = new cCommand1(pFrame, pVariables); this->pCommands[COMMAND2] = new cCommand2(pFrame, pVariables); this->pCommands[COMMAND3] = new cCommand3(pFrame, pVariables); this->pCommands[COMMAND13] = new cCommand13(pFrame); this->pCommands[COMMAND12] = new cCommand12(pFrame); this->pCommands[COMMAND14] = new cCommand14(pFrame); this->pCommands[COMMAND15] = new cCommand15(pFrame, pVariables); this->pCommands[COMMAND160] = new cCommand160(pFrame); this->pCommands[COMMAND157] = new cCommand157(pFrame); this->pCommands[COMMAND159] = new cCommand159(pFrame); this->pCommands[COMMAND180] = new cCommand180(pFrame); }
pCommandSet->pCommands[this->pFrame->getCurrentCommand()]->setNewData(); pCommandSet->pCommands[this->pFrame->getCurrentCommand()]->send();
#include "susutypes.h" #include "frame.h" #include "observer.h" #include "linklayer.h" #include "variables.h" #include "commandset.h" #include "frtosWrapper.h" #define MAX_BUFFER_SIZE (tU8)255 class cDwart: private iObserver, public iActiveObject { public: cDwart(Variables *pVariables); virtual void eventHandle(const iObservable* pObservable); virtual void run(void); private: cCommandSet *pCommandSet; cLinkLayer *pLinkLayer; cFrame *pFrame; tU8 buffer[MAX_BUFFER_SIZE]; tBoolean isToken; static const tU8 deviceID[5]; };
#include "susuassert.h" #include "frame.h" #include <stddef.h> #include "dwart.h" #define SHORT_ADDR (tU8)0 #define PREAMBULS_COUNT (tU8)7 #define DWART_WAITING (tU32) (50/portTICK_PERIOD_MS) const tU8 cDwart::deviceID[5] = {(tU8)0x37,(tU8)0x04,(tU8)0x00,(tU8)0x00,(tU8)0x01}; /******************************************************************************* * Function: constructor * Description: cLinkLayer, cFrame cCommandSet * ******************************************************************************/ cDwart::cDwart(Variables *pVariables) { this->pLinkLayer = new cLinkLayer(this->buffer,MAX_BUFFER_SIZE, this->buffer, PREAMBULS_COUNT); this->pFrame = new cFrame((tU8*)deviceID, SHORT_ADDR,this->pLinkLayer); this->pCommandSet = new cCommandSet(this->pFrame, pVariables); this->pLinkLayer->addObserver(this); this->isToken = FALSE; } /******************************************************************************* * Function: eventHandle * Description: . ******************************************************************************/ void cDwart::eventHandle(const iObservable* pObservable) { ASSERT(pObservable != NULL); this->isToken = TRUE; } /******************************************************************************* * Function: run * Description: ******************************************************************************/ void cDwart::run(void) { for(;;) { if (this->isToken) { this->isToken = FALSE; if (this->pFrame->decode() == FE_good) { pCommandSet->pCommands[this->pFrame->getCurrentCommand()]->setNewData(); pCommandSet->pCommands[this->pFrame->getCurrentCommand()]->send(); } } oRTOS.taskDelay(DWART_WAITING); } }
void main( void ) { const cAdcDirector* pAdcDirector = new cAdcDirector(); pAdcDirector->startConversion(); cVariables *pVariables = new cVariables(pAdcDirector); oRTOS.taskCreate(pVariablesDirector, VARIABLESDIRECTOR_STACK_SIZE, VARIABLESDIRECTOR_PRIORITY, "Var"); cDwart *pDwart = new cDwart(pVariablesDirector); oRTOS.taskCreate(pDwart, DWART_STACK_SIZE, DWART_PRIORITY, "Dwart"); ... oRTOS.startScheduler(); }
Source: https://habr.com/ru/post/262133/
All Articles