bootloader 里面不能运行 canfestiavl

发布于 2020-07-29 11:30:15

最近想做一个带bootloader的项目。之前原来的项目里带了can的通讯也是用RTT里面的canfestival做的,可以正常运行和使用,但是为了IAP的升级把 flash的起始地址偏移了一下从LR_IROM1 0x08000000 改为 LR_IROM1 0x08020000,can的运行就存在问题,但是如果屏蔽can功能在IAP下其他程序都可以正常运行。以下是具体问题描述。
1,首先修改link.sct为

LR_IROM1 0x08020000 0x000e0000  {    ; load region size_region 
  ER_IROM1 0x08020000 0x000e0000  {  ; load address = execution address 
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20020000 0x00060000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

2,在main.c里加入了

static int ota_app_vtor_reconfig(void)
{
    #define NVIC_VTOR_MASK   0x3FFFFF80
    /* Set the Vector Table base location by user application firmware definition */
    SCB->VTOR = 0x08020000 & NVIC_VTOR_MASK;
    return 0;
}
INIT_BOARD_EXPORT(ota_app_vtor_reconfig);

3运行了一段时间后在drv_can.c里面会把hcan->State = HAL_CAN_STATE_ERROR;赋值
具体原因是0号发送邮箱再新发送要求来的时候没有准备好,我不清楚为什么会这样?

static int _can_sendmsg(struct rt_can_device *can, const void *buf, rt_uint32_t box_num)
{
    CAN_HandleTypeDef *hcan;
    hcan = &((struct stm32_can *) can->parent.user_data)->CanHandle;
    struct rt_can_msg *pmsg = (struct rt_can_msg *) buf;
    CAN_TxHeaderTypeDef txheader = {0};
    HAL_CAN_StateTypeDef state = hcan->State;

    /* Check the parameters */
    RT_ASSERT(IS_CAN_DLC(pmsg->len));

    if ((state == HAL_CAN_STATE_READY) ||
            (state == HAL_CAN_STATE_LISTENING))
    {
        /*check select mailbox  is empty */
        switch (1 << box_num)
        {
        case CAN_TX_MAILBOX0:
            if (HAL_IS_BIT_SET(hcan->Instance->TSR, CAN_TSR_TME0) != SET)
            {
                /* Change CAN state */
           **     hcan->State = HAL_CAN_STATE_ERROR;**
                /* Return function status */
                return -RT_ERROR;
            }
            break;

4,所以程序一直在can.c里的_can_int_tx进行死循环

rt_inline int _can_int_tx(struct rt_can_device *can, const struct rt_can_msg *data, int msgs)
{
    int size;
    struct rt_can_tx_fifo *tx_fifo;

    RT_ASSERT(can != RT_NULL);

    size = msgs;
    tx_fifo = (struct rt_can_tx_fifo *) can->can_tx;
    RT_ASSERT(tx_fifo != RT_NULL);

    while (msgs)
    {
        rt_base_t level;
        rt_uint32_t no;
        rt_uint32_t result;
        struct rt_can_sndbxinx_list *tx_tosnd = RT_NULL;

        rt_sem_take(&(tx_fifo->sem), RT_WAITING_FOREVER);
        level = rt_hw_interrupt_disable();
        tx_tosnd = rt_list_entry(tx_fifo->freelist.next, struct rt_can_sndbxinx_list, list);
        RT_ASSERT(tx_tosnd != RT_NULL);
        rt_list_remove(&tx_tosnd->list);
        rt_hw_interrupt_enable(level);

        no = ((rt_uint32_t)tx_tosnd - (rt_uint32_t)tx_fifo->buffer) / sizeof(struct rt_can_sndbxinx_list);
        tx_tosnd->result = RT_CAN_SND_RESULT_WAIT;
        if (can->ops->sendmsg(can, data, no) != RT_EOK)
        {
            /* send failed. */
            level = rt_hw_interrupt_disable();
            rt_list_insert_after(&tx_fifo->freelist, &tx_tosnd->list);
            rt_hw_interrupt_enable(level);
            rt_sem_release(&(tx_fifo->sem));
          **  continue;**在这里会死循环
        }

问题:为什么原来的程序没有出现这样的情况,而改了FLASH的启动偏移反而出现了这样的情况???请大神们来给点思路。这个问题找了很久了。

查看更多

关注者
0
被浏览
131
JQRR_7669
JQRR_7669 认证专家 2020-07-29

看看CAN的初始化是不是在ota_app_vtor_reconfig之前了,如果是将CAN初始化延后就行了。RW_IRAM1 没必要也偏移0x20000

1 个回答

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友