STM32F103xxxx在应用程序编程中使用Arduino

STM32F103xxxx在应用程序编程中使用Arduino,arduino,stm32,Arduino,Stm32,我正在使用Arduino_STM32 rogerclark的图书馆。 现在我想开发一个类似于引导加载程序的应用程序内编程(IAP)。从SD卡获取代码并存储在0x801000的控制器闪存中,然后跳转到该位置并运行加载的新应用程序 代码取自SD并成功存储到flash中,但在跳转函数调用其打印null后,如下所示 13:29:04.933[RX]-开始 13:29:07.970[RX]-20480已成功上载 努努努努努努努努努努努努努努努努努努努努努努努努努努努努努努尔 我的主要IAP代码是 头文件

我正在使用Arduino_STM32 rogerclark的图书馆。 现在我想开发一个类似于引导加载程序的应用程序内编程(IAP)。从SD卡获取代码并存储在0x801000的控制器闪存中,然后跳转到该位置并运行加载的新应用程序

代码取自SD并成功存储到flash中,但在跳转函数调用其打印null后,如下所示

13:29:04.933[RX]-开始

13:29:07.970[RX]-20480已成功上载

努努努努努努努努努努努努努努努努努努努努努努努努努努努努努努尔

我的主要IAP代码是

头文件

#include <SPI.h>
#include <SD.h>
#include <EEPROM.h>
#include <stdint.h>
#include "libmaple/scb.h"
#include "usb_lib.h"

typedef void (*FuncPtr)(void);
#define SCS_BASE   ((u32)0xE000E000)
#define NVIC_BASE  (SCS_BASE + 0x0100)
#define SCB_BASE   (SCS_BASE + 0x0D00)
#define SCS      0xE000E000
#define NVIC     (SCS+0x100)
#define SCB      (SCS+0xD00)
#define STK      (SCS+0x10)

#define SCB_VTOR (SCB+0x08)
#define STK_CTRL (STK+0x00)

#define RCC   ((u32)0x40021000)
#define RCC_CR      RCC
#define RCC_CFGR    (RCC + 0x04)
#define RCC_CIR     (RCC + 0x08)

#define USB_LP_IRQ  ((u8)0x14)
#define SET_REG(addr,val) do{ *(volatile uint32_t*)(addr)=val;} while(0)
#define GET_REG(addr)     (*(vu32*)(addr))

#define pRCC ((rcc_reg_map *) RCC)

typedef struct {
  u8 NVIC_IRQChannel;
  u8 NVIC_IRQChannelPreemptionPriority;
  u8 NVIC_IRQChannelSubPriority;
  bool NVIC_IRQChannelCmd; /* TRUE for enable */
} NVIC_InitTypeDef;

#define RegBase  (0x40005C00L)
#define CNTR    ((volatile unsigned *)(RegBase + 0x40))
#define _SetCNTR(wRegValue)  (*CNTR   = (u16)wRegValue)
#define _GetCNTR()   ((u16) *CNTR)
#define ISTR    ((volatile unsigned *)(RegBase + 0x44))
#define _SetISTR(wRegValue)  (*ISTR   = (u16)wRegValue)
#define _GetISTR()   ((u16) *ISTR)

void setupFLASH();
void usbDsbISR(void);
void nvicInit(NVIC_InitTypeDef *NVIC_InitStruct);
void nvicDisableInterrupts();
void setMspAndJump(u32 usrAddr);
void systemReset(void);
RESULT usbPowerOff(void);



void setupFLASH()
{
  /* configure the HSI oscillator */
  if ((pRCC->CR & 0x01) == 0x00)
  {
    u32 rwmVal = pRCC->CR;
    rwmVal |= 0x01;
    pRCC->CR = rwmVal;
  }

  /* wait for it to come on */
  while ((pRCC->CR & 0x02) == 0x00) {}
}

 void usbDsbISR(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_IRQ;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = FALSE;
  nvicInit(&NVIC_InitStructure);
}

void nvicInit(NVIC_InitTypeDef *NVIC_InitStruct)
{
  u32 tmppriority = 0x00;
  u32 tmpreg      = 0x00;
  u32 tmpmask     = 0x00;
  u32 tmppre      = 0;
  u32 tmpsub      = 0x0F;

  scb_reg_map *rSCB = (scb_reg_map *) SCB_BASE;
  nvic_reg_map *rNVIC = (nvic_reg_map *) NVIC_BASE;


  /* Compute the Corresponding IRQ Priority --------------------------------*/
  tmppriority = (0x700 - (rSCB->AIRCR & (u32)0x700)) >> 0x08;
  tmppre = (0x4 - tmppriority);
  tmpsub = tmpsub >> tmppriority;

  tmppriority = (u32)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;
  tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;

  tmppriority = tmppriority << 0x04;
  tmppriority = ((u32)tmppriority) << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);

  tmpreg = rNVIC->IP[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)];
  tmpmask = (u32)0xFF << ((NVIC_InitStruct->NVIC_IRQChannel & (u8)0x03) * 0x08);
  tmpreg &= ~tmpmask;
  tmppriority &= tmpmask;
  tmpreg |= tmppriority;

  rNVIC->IP[(NVIC_InitStruct->NVIC_IRQChannel >> 0x02)] = tmpreg;

   /* Enable the Selected IRQ Channels --------------------------------------*/
    rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel >> 0x05)] =
    (u32)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (u8)0x1F);
}

 void nvicDisableInterrupts()
{
  nvic_reg_map *rNVIC = (nvic_reg_map *) NVIC_BASE;
  rNVIC->ICER[0] = 0xFFFFFFFF;
  rNVIC->ICER[1] = 0xFFFFFFFF;
  rNVIC->ICPR[0] = 0xFFFFFFFF;
  rNVIC->ICPR[1] = 0xFFFFFFFF;

  SET_REG(STK_CTRL, 0x04); /* disable the systick, which operates separately from nvic */
}

void usbDsbBus(void)
{
  // setPin(USB_DISC_BANK,USB_DISC_PIN);
  usbPowerOff();
  // SET_REG(USB_DISC_CR,
  // (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_OUTPUT);
  // resetPin(USB_DISC_BANK, USB_DISC_PIN); /* Pull DP+ down */
  // volatile unsigned x = 500000; do { ; }while(--x);
  // SET_REG(USB_DISC_CR,
  // (GET_REG(USB_DISC_CR) & USB_DISC_CR_MASK) | USB_DISC_CR_INPUT); //Sets the PA12 as floating 
input
}

RESULT usbPowerOff(void)
{
   #define CNTR_PDWN   (0x0002) /* Power DoWN */
   #define CNTR_FRES   (0x0001) /* Force USB RESet */
  _SetCNTR(CNTR_FRES);
  _SetISTR(0);
  _SetCNTR(CNTR_FRES + CNTR_PDWN);

  /* note that all weve done here is powerdown the
     usb peripheral. we have no disabled the clocks,
     pulled the USB_DISC_PIN pin back up, or reset the
     application state machines */

  return USB_SUCCESS;
}

void systemReset(void)
{
  SET_REG(RCC_CR, GET_REG(RCC_CR) | 0x00000001);
  SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xF8FF0000);
  SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFEF6FFFF);
  SET_REG(RCC_CR, GET_REG(RCC_CR) & 0xFFFBFFFF);
  SET_REG(RCC_CFGR, GET_REG(RCC_CFGR) & 0xFF80FFFF);
  SET_REG(RCC_CIR, 0x00000000);  /* disable all RCC interrupts */
}

void setMspAndJump(u32 usrAddr)
{
  // Dedicated function with no call to any function (appart the last call)
  // This way, there is no manipulation of the stack here, ensuring that GGC
  // didn't insert any pop from the SP after having set the MSP.
  typedef void (*funcPtr)(void);
  u32 jumpAddr = *(vu32 *)(usrAddr + 0x04); /* reset ptr in vector table */

  funcPtr usrMain = (funcPtr) jumpAddr;

  SET_REG(SCB_VTOR, (vu32) (usrAddr));

  asm volatile("msr msp, %0"::"g"(*(volatile u32 *)usrAddr));

  usrMain();                                /* go! */
}
#包括
#包括
#包括
#包括
#包括“libmaple/scb.h”
#包括“usb_lib.h”
类型定义无效(*FuncPtr)(无效);
#定义SCS_基((u32)0xE000E000)
#定义NVIC_基地(SCS_基地+0x0100)
#定义SCB_基地(SCS_基地+0x0D00)
#定义SCS 0xE000E000
#定义NVIC(SCS+0x100)
#定义SCB(SCS+0xD00)
#定义STK(SCS+0x10)
#定义SCB\u VTOR(SCB+0x08)
#定义STK\U CTRL(STK+0x00)
#定义RCC((u32)0x40021000)
#定义RCC\u CR RCC
#定义RCC\u CFGR(RCC+0x04)
#定义RCC_CIR(RCC+0x08)
#定义USB_LP_IRQ((u8)0x14)
#定义SET_REG(addr,val)do{*(volatile uint32_t*)(addr)=val;}while(0)
#定义GET_REG(addr)(*(vu32*)(addr))
#定义pRCC((rcc_reg_map*)rcc)
类型定义结构{
u8 NVIC_IRQChannel;
u8 NVIC_irqChannel抢占优先级;
u8 NVIC_irqchannel次优先级;
bool NVIC_IRQChannelCmd;/*启用时为TRUE*/
}NVIC_InitTypeDef;
#定义RegBase(0x40005C00L)
#定义CNTR((易失性无符号*)(RegBase+0x40))
#定义_SetCNTR(wRegValue)(*CNTR=(u16)wRegValue)
#定义_GetCNTR()((u16)*CNTR)
#定义ISTR((易失性无符号*)(RegBase+0x44))
#定义_SetISTR(wRegValue)(*ISTR=(u16)wRegValue)
#定义_GetISTR()((u16)*ISTR)
void setupFLASH();
无效usbDsbISR(无效);
void nvicInit(NVIC_InitTypeDef*NVIC_InitStruct);
void nvicDisableInterrupts();
void setMspAndJump(u32 usrAddr);
作废系统重置(作废);
结果usbPowerOff(无效);
void setupFLASH()
{
/*配置HSI振荡器*/
如果((pRCC->CR&0x01)==0x00)
{
u32 rwmVal=pRCC->CR;
rwmVal |=0x01;
pRCC->CR=rwmVal;
}
/*等它来吧*/
而((pRCC->CR&0x02)==0x00{}
}
无效usbDsbISR(无效)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel=USB_LP_IRQ;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=FALSE;
nvicInit(&NVIC_InitStructure);
}
void nvicInit(NVIC_InitTypeDef*NVIC_InitStruct)
{
u32 TMPPRORITY=0x00;
u32 tmpreg=0x00;
u32 tmpmask=0x00;
u32 tmppre=0;
u32 tmpsub=0x0F;
scb_注册地图*rSCB=(scb_注册地图*)scb_基地;
nvic_reg_map*rNVIC=(nvic_reg_map*)nvic_基地;
/*计算相应的IRQ优先级--------------------------------*/
TMPPRORITY=(0x700-(rSCB->Airr&(u32)0x700))>>0x08;
tmppre=(0x4-tmppriority);
tmpsub=tmpsub>>TMPPRORITY;
tmppriority=(u32)NVIC_InitStruct->NVIC_irqchannelpreemption优先级NVIC_IRQChannelSubPriority&tmpsub;
tmppriority=tmppriority IP[(NVIC_InitStruct->NVIC_IRQChannel>>0x02)];
tmpmask=(u32)0xFF NVIC_IRQ通道和(u8)0x03)*0x08);
tmpreg&=~tmpmask;
tmppriority&=tmpmask;
tmpreg |=TMPPRORITY;
rNVIC->IP[(NVIC_InitStruct->NVIC_IRQChannel>>0x02)]=tmpreg;
/*启用选定的IRQ通道--------------------------------------*/
rNVIC->ISER[(NVIC_InitStruct->NVIC_IRQChannel>>0x05)]=
(u32)0x01 NVIC_IRQ通道和(u8)0x1F);
}
void nvicDisableInterrupts()
{
nvic_reg_map*rNVIC=(nvic_reg_map*)nvic_基地;
rNVIC->ICER[0]=0xFFFFFFFF;
rNVIC->ICER[1]=0xFFFFFFFF;
rNVIC->ICPR[0]=0xFFFFFFFF;
rNVIC->ICPR[1]=0xFFFFFFFF;
设置_REG(STK_CTRL,0x04);/*禁用systick,它与nvic分开运行*/
}
无效USBDSBUS(无效)
{
//setPin(USB光盘组、USB光盘PIN);
usbPowerOff();
//设置注册表(USB盘),
//(获取_REG(USB_DISC_CR)和USB_DISC_CR_MASK)| USB_DISC_CR_输出);
//重置插针(USB_盘_盘组,USB_盘_插针);/*下拉DP+*/
//易失性无符号x=500000;do{;}而(--x);
//设置注册表(USB盘),
//(GET_REG(USB_DISC_CR)&USB_DISC_CR_MASK)| USB_DISC_CR_INPUT);//将PA12设置为浮动
输入
}
结果usbPowerOff(无效)
{
#定义CNTR_PDWN(0x0002)/*断电*/
#定义CNTR_FRES(0x0001)/*强制USB重置*/
_SetCNTR(CNTR_FRES);
_SetISTR(0);
_SetCNTR(CNTR_FRES+CNTR_PDWN);
/*请注意,我们在这里所做的只是关闭电源
usb外设。我们没有禁用时钟,
将USB_盘_引脚拔回,或重置
应用程序状态机*/
回归成功;
}
作废系统重置(作废)
{
设置注册码(RCC注册码,获取注册码(RCC注册码)| 0x00000001);
设置注册表(RCC\U CFGR,获取注册表(RCC\U CFGR)&0xF8FF0000);
SET_REG(RCC_CR,GET_REG(RCC_CR)&0xFEF6FFFF);
设置注册(RCC注册、获取注册(RCC注册)和0xFFFBFFFF);
设置注册表(RCC\U CFGR,获取注册表(RCC\U CFGR)&0xFF80FFFF);
设置_REG(RCC_CIR,0x00000000);/*禁用所有RCC中断*/
}
void setMspAndJump(u32 usrAddr)
{
//不调用任何函数的专用函数(最后一次调用)
//通过这种方式,这里没有对堆栈的操作,确保GGC
//设置MSP后,未从SP插入任何pop。
类型定义无效(*funcPtr)(无效);
u32 jumpAddr=*(vu32*)(usrAddr+0x04);/*在向量表中重置ptr*/
funcPtr usrMain=(funcPtr)jumpAddr;
SET_REG(SCB_VTOR,(vu32)(usrAddr));
asm volatile(“msr msp,%0”::“g”(*(volatile u32*)usrAddr));
usrMain();/*开始*/
}
主要代码是

    #include "core_test.h"

#define CS          PB9
File myFile;
char Name[15] = "ASCII.bin";

uint32_t Count = 0;
uint32_t total = 0;

#define FLASH_FLAG_EOP                 ((uint32_t)0x00000020)  /* FLASH End of Operation flag */
#define FLASH_FLAG_PGERR               ((uint32_t)0x00000004)  /* FLASH Program error flag */
#define FLASH_FLAG_WRPRTERR            ((uint32_t)0x00000010)  /* FLASH Write protected error flag */

#define myFLASH_APP_ADDR 0x08000000
#define FLASH_APP_ADDR 0x08010000 //The first application start address (stored in FLASH)
#define STM_PAGE_SIZE 2048         //Note: The FLASH page size of STM32F103ZET6 is 2K.

//****************************************************************************************************
// Global variable declaration
char buff[STM_PAGE_SIZE];
int res;
unsigned int br;

void Jump2App(uint32_t Addr)
{
  if (((*(uint32_t*)Addr) & 0x2FFE0000) == 0x20000000) //Check if the top address of the stack is legal.
  {
    //    FLASH_Lock();
    usbDsbISR(); //Serial1.println("1");
    nvicDisableInterrupts(); //Serial1.println("2");
    usbDsbBus(); //Serial1.println("3");
    // Does nothing, as PC12 is not connected on teh Maple mini according to the schemmatic     setPin(GPIOC, 12); // disconnect usb from host. todo, macroize pin
    systemReset(); // resets clocks and periphs, not core regs
    //Serial1.println("4");
    setMspAndJump(Addr);
  }
}
void FirmwareUpdate(void)
{
  int PageOffest = 0;
  int ByteOffest;
  if (! IsFileExists(Name)) return;
  myFile = SD.open(Name);

  while (1)
  {
    if (Read_data_from_File(buff))
    {
      FLASH_Unlock();
      //      FLASH_ClearFlag(((uint16_t)0x00000034));
      //      FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR);
      FLASH_ErasePage(FLASH_APP_ADDR + PageOffest);
      for (ByteOffest = 0; ByteOffest < STM_PAGE_SIZE; ByteOffest += 2)
      {
        total = total + 2;
        FLASH_ProgramHalfWord(FLASH_APP_ADDR + PageOffest + ByteOffest, *(uint16_t*)(buff + ByteOffest));
      }
      FLASH_Lock();
      PageOffest += STM_PAGE_SIZE;
      //      Serial1.println(PageOffest);
    }
    else if (myFile.size() <= total) break;
  }
  myFile.close();
  Serial1.println(total);
  //myFile.close();
}

void setup()
{
  afio_cfg_debug_ports(AFIO_DEBUG_SW_ONLY);
  Serial1.begin(9600);
  if (!SD.begin(CS))
  {
    Serial1.println("No SD............");
    Jump2App(FLASH_APP_ADDR);
  }
  delay(1000);
  Serial1.println("Starts............"); delay(2000);
  FirmwareUpdate();
  Jump2App(FLASH_APP_ADDR);
  while (1);
}

void loop()
{}

bool IsFileExists(char FileName[])
{
  if (SD.exists(FileName)) return 1;
  else  return 0;
}

bool Read_data_from_File(char str[])
{
  memset(str, 255, 2048);
  uint16_t i = 0;
  if (myFile.size() < total)
  {
    //memset(str, 255, 2048);
    //    Serial1.println("File Closed");
    //    Serial1.println(total);
    return 0;
  }
  if (myFile)
  {
    while (i < 2048)
    {
      str[i++] = myFile.read();
      Count = Count + 1;
      if (myFile.size() < Count)
      {
        //memset(str, 255, 2048);
        //        Serial1.println("File Closed");
        //        Serial1.println(Count);
        return 1;
      }
    }
  }
  else return 0;
}
#包括“core_test.h”
#定义CS PB9
文件myFile;
字符名[15]=“ASCII.bin”;
uint32_t计数=0;
uint32_t总计=0;
#定义FLASH\u FLAG\u EOP((uint32\u t)0x00000020)/*FLASH操作结束标志*/
#定义FLASH_FLAG_PGERR