Forum : ST7/STM8
Post Information | Post |
---|---|
October 26, 2009 - 3:57pm
|
Hi all, We got an interesting request concerning in-application programming: As the STM8 protects the flash on a number of blocks of memory starting at address 0x8000 (configurable through option bytes), the interrupt vector table located at address 0x8000 is read-only in IAP mode. So what happens to your interrupts when you need to support In-Application Programming (IAP)? ST recommends that you relocate your interrupt vectors at a different address, for instance 0x9000. This can be done in your C files through the INTVECTOR(0x9000) directive. Here is an example file that declares such a "leaping" IRQ vector table. The following C file will define the initial interrupt vector table. Feel free to use it in your projects. Regards, //------------------------------------------------------------------------------ // redirect_irq_table.c // // When writing In-Application Programming (IAP) using the STM8, it may // be necessary to define a second interrupt vector table. This is because // the STM8 interrupt vectors are at addresses 0x8000-0x8080, which is // part of the Flash that may be write-protected (in order to protect // the User Boot Code from erasure). This write protection is made through // STM8 option bytes // In case the interrupt vectors are write-protected, it will be necessary // to redirect them to an area which can be reprogrammed. // This file will create a redirection vector table. // // Notes: // - The USER_INTERRUPT_TABLE_ADDRESS macro must contain the address of the // actual vector table you will be using. // - The INTVECTOR Compiler directive will have to be used for the user // application in order to remap the user interrupt table. // For example, INTVECTOR(0x9000) will relocate vectors starting at 0x9000. // //------------------------------------------------------------------------------ // Copyright (c) Raisonance S.A.S, 2009. //------------------------------------------------------------------------------ // Define the ISR type, which is a pointer to an interrupt function typedef char far* ISR; // far* is necessary for 3-bytes address // Change the USER_INTERRUPT_TABLE_ADDRESS macro to point to the actual // vector table you will be using. #define USER_INTERRUPT_TABLE_ADDRESS 0x9000 // At absolute address (0x8008 + interruptNumber * 4) place a 0x82 byte, // then the 3-bytes address of the handler at 0x8008 code unsigned char vect0_head = 0x82; at 0x8009 code ISR vect0 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x08); at 0x800C code unsigned char vect1_head = 0x82; at 0x800D code ISR vect1 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x0C); at 0x8010 code unsigned char vect2_head = 0x82; at 0x8011 code ISR vect2 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x10); at 0x8014 code unsigned char vect3_head = 0x82; at 0x8015 code ISR vect3 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x14); at 0x8018 code unsigned char vect4_head = 0x82; at 0x8019 code ISR vect4 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x18); at 0x801C code unsigned char vect5_head = 0x82; at 0x801D code ISR vect5 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x1C); at 0x8020 code unsigned char vect6_head = 0x82; at 0x8021 code ISR vect6 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x20); at 0x8024 code unsigned char vect7_head = 0x82; at 0x8025 code ISR vect7 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x24); at 0x8028 code unsigned char vect8_head = 0x82; at 0x8029 code ISR vect8 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x28); at 0x802C code unsigned char vect9_head = 0x82; at 0x802D code ISR vect9 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x2C); at 0x8030 code unsigned char vect10_head = 0x82; at 0x8031 code ISR vect10 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x30); at 0x8034 code unsigned char vect11_head = 0x82; at 0x8035 code ISR vect11 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x34); at 0x8038 code unsigned char vect12_head = 0x82; at 0x8039 code ISR vect12 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x38); at 0x803C code unsigned char vect13_head = 0x82; at 0x803D code ISR vect13 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x3C); at 0x8040 code unsigned char vect14_head = 0x82; at 0x8041 code ISR vect14 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x40); at 0x8044 code unsigned char vect15_head = 0x82; at 0x8045 code ISR vect15 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x44); at 0x8048 code unsigned char vect16_head = 0x82; at 0x8049 code ISR vect16 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x48); at 0x804C code unsigned char vect17_head = 0x82; at 0x804D code ISR vect17 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x4C); at 0x8050 code unsigned char vect18_head = 0x82; at 0x8051 code ISR vect18 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x50); at 0x8054 code unsigned char vect19_head = 0x82; at 0x8055 code ISR vect19 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x54); at 0x8058 code unsigned char vect20_head = 0x82; at 0x8059 code ISR vect20 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x58); at 0x805C code unsigned char vect21_head = 0x82; at 0x805D code ISR vect21 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x5C); at 0x8060 code unsigned char vect22_head = 0x82; at 0x8061 code ISR vect22 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x60); at 0x8064 code unsigned char vect23_head = 0x82; at 0x8065 code ISR vect23 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x64); at 0x8068 code unsigned char vect24_head = 0x82; at 0x8069 code ISR vect24 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x68); at 0x806C code unsigned char vect25_head = 0x82; at 0x806D code ISR vect25 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x6C); at 0x8070 code unsigned char vect26_head = 0x82; at 0x8071 code ISR vect26 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x70); at 0x8074 code unsigned char vect27_head = 0x82; at 0x8075 code ISR vect27 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x74); at 0x8078 code unsigned char vect28_head = 0x82; at 0x8079 code ISR vect28 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x78); at 0x807C code unsigned char vect29_head = 0x82; at 0x807D code ISR vect29 = (ISR)(USER_INTERRUPT_TABLE_ADDRESS + 0x7C); |