查看: 6365|回复: 8

[已解决] FSL_LIN_2.x_STACK_Package_4.5.9软件包中lin_lld_uart_int_disable问题

[复制链接]

该用户从未签到

4

主题

19

帖子

0

新手上路

Rank: 1

积分
46
最后登录
2020-5-29
发表于 2019-2-28 13:45:30 | 显示全部楼层 |阅读模式
FSL_LIN_2.x_STACK_Package_4.5.9软件包中调用lin_lld_uart_int_disable会进入死循环;

我用的芯片是KEA128,KDS编译器, 移植了官方的FSL_LIN_2.x_STACK_Package_4.5.9 软件包,因为在应用程序中需要对flash写操作,写flash之前需要先关闭全局中断,但是直接关全局中断,flash写完后恢复全局中断,lin通讯无法恢复,后来我使用FSL_LIN_2.x_STACK_Package_4.5.9 中自带的函数先关闭lin,再关闭全局中断,lin通讯能恢复,代码如下,但偶尔会在调用lin_lld_uart_int_disable()时进入死循环,进入死循环时,仿真查看程序停留在

    while(state != IDLE)
    {}

state = RECV_SYN;

请教下有什么办法解决这个问题?


写flash程序:
if((FLASH_LOCATION_K % FLASH_SECTOR_SIZE) == 0)               
        {
                WDog1_Clear(MyWDog1Ptr);                 /* Clear watchdog timer */
                l_sys_irq_disable(LI0);
                //__disable_irq();
                __DI();      
                //__DI();
                //__DI(); /* Disable interrupts */        // 直锟接斤拷止锟叫断猴拷通讯锟睫凤拷锟街革拷  鍟婂晩鍟?
                #if 1
                FLASH_EraseSector(FLASH_LOCATION_K);       
                  if (FLASH_Program(FLASH_LOCATION_K, buff, len+4) != FLASH_ERR_SUCCESS)
                  {
                        res = 0xFF;
                        autoCalibration.error |= ERROR_BIT4;        // 锟斤拷锟斤拷flash锟斤拷锟斤拷        test...
                }
                else
                {
                        autoCalibration.test++;
                }
                #endif
                lin_goto_idle_state();
                l_sys_irq_restore(LI0);
                //__enable_irq();
                __EI();                              /* Enable interrupts */        // 锟斤拷锟铰匡拷锟叫断猴拷时锟斤拷锟睫凤拷锟斤拷锟叫o拷 flash写锟斤拷锟斤拷锟斤拷锟斤拷锟轿灰伙拷危锟?
                //__EI();
                //__EI();
                //sSW_Reset();        //        锟斤拷位锟斤拷锟斤拷锟絣_sys_irq_disable 锟截憋拷LIN锟叫断撅拷山锟斤拷锟斤拷锟铰匡拷锟叫讹拷锟睫凤拷锟街革拷通讯锟斤拷锟斤拷
        }


#define IDLE                0x00          /**< IDLE state */
#define SEND_BREAK          0x01          /**< Send break field state */
#define SEND_PID            0x02          /**< send PID state */
#define RECV_SYN            0x03          /**< receive synchronize state */
#define RECV_PID            0x04          /**< receive PID state */
#define IGNORE_DATA         0x05          /**< ignore data state */
#define RECV_DATA           0x06          /**< receive data state */
#define SEND_DATA           0x07          /**< send data state */
#define SEND_DATA_COMPLETED 0x08          /**< send data completed state */
#define PROC_CALLBACK       0x09          /**< proceduce callback state */
#define SLEEP_MODE          0x0A          /**< sleep mode state */
#define UNINIT              0xFF          /**< uninitialize state */



void lin_lld_uart_int_disable
(
)
{
    /*--------------------------------------------------------------------*/
    /* Can't disable in interrupt context */
    if ((state == PROC_CALLBACK) || (state == UNINIT) || (state == SLEEP_MODE))
    {
        return;
    }

    while(state != IDLE)
    {}
    /* Disable UART Channel */
    pUART->uartcr2.byte &= ~(UARTCR2_RE_MASK | UARTCR2_RIE_MASK);
    /* Disable timeout interrupt 0 channel */
} /* End function lin_lld_UART_int_disable() */

最佳答案

shuxmpx123 发表于 2019-3-5 16:33 恩  问题是我不知道LIN数据什么时候处理好,直接关闭UART的话,如果正在接收或发送数据帧,就可能导致LIN ... 楼主你好,刚才我帮你问了我们汽车team的一个比较熟悉LIN ...
回复

使用道具 举报

该用户从未签到

4

主题

19

帖子

0

新手上路

Rank: 1

积分
46
最后登录
2020-5-29
 楼主| 发表于 2019-2-28 14:16:40 | 显示全部楼层
刚刚又验证了一个退而求其次的办法,但是程序是不会进死循环,但是LIN通讯在写flash时有时候会丢帧,不是太理想:
代码如下:
if((FLASH_LOCATION_K % FLASH_SECTOR_SIZE) == 0)                // 偶锟斤拷岣次伙拷锟斤拷榭达拷欠锟斤拷强锟斤拷殴锟斤拷锟轿?
        {
                WDog1_Clear(MyWDog1Ptr);                 /* Clear watchdog timer */
                //l_sys_irq_disable(LI0);
                //__disable_irq();
                __DI();      
                //__DI();
                //__DI(); /* Disable interrupts */        // 直锟接斤拷止锟叫断猴拷通讯锟睫凤拷锟街革拷  鍟婂晩鍟?
                #if 1
                FLASH_EraseSector(FLASH_LOCATION_K);       
                  if (FLASH_Program(FLASH_LOCATION_K, buff, len+4) != FLASH_ERR_SUCCESS)
                  {
                        res = 0xFF;
                        autoCalibration.error |= ERROR_BIT4;        // 锟斤拷锟斤拷flash锟斤拷锟斤拷        test...
                }
                else
                {
                        autoCalibration.test++;
                }
                #endif
                //lin_goto_idle_state();
                //l_sys_irq_restore(LI0);
                lin_goto_idle_state();
                //__enable_irq();
                __EI();                              /* Enable interrupts */        // 锟斤拷锟铰匡拷锟叫断猴拷时锟斤拷锟睫凤拷锟斤拷锟叫o拷 flash写锟斤拷锟斤拷锟斤拷锟斤拷锟轿灰伙拷危锟?
                //__EI();
                //__EI();
                //sSW_Reset();        //        锟斤拷位锟斤拷锟斤拷锟絣_sys_irq_disable 锟截憋拷LIN锟叫断撅拷山锟斤拷锟斤拷锟铰匡拷锟叫讹拷锟睫凤拷锟街革拷通讯锟斤拷锟斤拷
        }
回复 支持 反对

使用道具 举报

该用户从未签到

4

主题

19

帖子

0

新手上路

Rank: 1

积分
46
最后登录
2020-5-29
 楼主| 发表于 2019-2-28 14:23:35 | 显示全部楼层
本帖最后由 shuxmpx123 于 2019-2-28 14:25 编辑

下面这个函数看上去没什么问题,是等一帧数据处理完之后再关中断,但是不清楚为什么会程序会死在那里。。。

还有一点,这个函数在某些状态下是直接返回,无法100%关闭中断的,也不太好,没有找到更好的关闭LIN通讯的函数了;
void lin_lld_uart_int_disable
(
)
{
    /*--------------------------------------------------------------------*/
    /* Can't disable in interrupt context */
    if ((state == PROC_CALLBACK) || (state == UNINIT) || (state == SLEEP_MODE))
    {
        return;
    }

    while(state != IDLE)
    {}
    /* Disable UART Channel */
    pUART->uartcr2.byte &= ~(UARTCR2_RE_MASK | UARTCR2_RIE_MASK);
    /* Disable timeout interrupt 0 channel */
} /* End function lin_lld_UART_int_disable() */
回复 支持 反对

使用道具 举报

该用户从未签到

4

主题

19

帖子

0

新手上路

Rank: 1

积分
46
最后登录
2020-5-29
 楼主| 发表于 2019-3-1 10:34:26 | 显示全部楼层
是不是用LIN的人少,怎么没人来讨论下。。。
回复 支持 反对

使用道具 举报

该用户从未签到

723

主题

6382

帖子

0

超级版主

Rank: 8Rank: 8

积分
25450
最后登录
2025-9-4
发表于 2019-3-5 13:59:14 | 显示全部楼层
shuxmpx123 发表于 2019-2-28 14:23
下面这个函数看上去没什么问题,是等一帧数据处理完之后再关中断,但是不清楚为什么会程序会死在那里。。。 ...

楼主你好。
我在想,如果你LIN数据处理好后,希望操作flash,而且操作flash那段时间内的LIN数据也不需要用。
你可以直接操作完数据之后,不调用LIN驱动,直接去控制UART模块关闭试试呢。
回复 支持 反对

使用道具 举报

该用户从未签到

4

主题

19

帖子

0

新手上路

Rank: 1

积分
46
最后登录
2020-5-29
 楼主| 发表于 2019-3-5 16:33:23 | 显示全部楼层
小恩GG 发表于 2019-3-5 13:59
楼主你好。
我在想,如果你LIN数据处理好后,希望操作flash,而且操作flash那段时间内的LIN数据也不需要 ...

恩  问题是我不知道LIN数据什么时候处理好,直接关闭UART的话,如果正在接收或发送数据帧,就可能导致LIN一直无法恢复通讯; 我一开始就是直接关闭总中断,发现有这个问题的;

后来使用void lin_lld_uart_int_disable 函数关闭UART中断,再关总中断,重新开中断能恢复通讯,但是void lin_lld_uart_int_disable 这个函数可能会进入死循环;

其实  lin_lld_uart_int_disable   这个函数就是等数据处理完后关中断,这样操作基本不会丢帧,但是不清楚是硬件还是软件BUG,会进入死循环;

使用二楼的代码,不会进入死循环,也能恢复通讯,但是直接关中断丢帧的概率比较大;

在LIN_2.x软件包里也没有找到更好的类似 lin_lld_uart_int_disable   功能的函数了。。
回复 支持 反对

使用道具 举报

该用户从未签到

723

主题

6382

帖子

0

超级版主

Rank: 8Rank: 8

积分
25450
最后登录
2025-9-4
发表于 2019-3-6 14:20:41 | 显示全部楼层
shuxmpx123 发表于 2019-3-5 16:33
恩  问题是我不知道LIN数据什么时候处理好,直接关闭UART的话,如果正在接收或发送数据帧,就可能导致LIN ...

楼主你好,刚才我帮你问了我们汽车team的一个比较熟悉LIN stack的同事。
他说,你可以直接关闭,等到flash操作好之后,可以重新初始化下lin,这样应该可以正常进行LIN通信。
回复 支持 反对

使用道具 举报

该用户从未签到

4

主题

19

帖子

0

新手上路

Rank: 1

积分
46
最后登录
2020-5-29
 楼主| 发表于 2019-3-6 15:33:49 | 显示全部楼层
小恩GG 发表于 2019-3-6 14:20
楼主你好,刚才我帮你问了我们汽车team的一个比较熟悉LIN stack的同事。
他说,你可以直接关闭,等到flas ...

好的,,感谢, 我现在是直接关闭,然后打开之前调用 lin_goto_idle_state, 我看了初始化函数 lin_lld_uart_init里面是先配置寄存器之后再调用lin_goto_idle_state,跟我现在的方法只是多了寄存器配置;
回复 支持 反对

使用道具 举报

该用户从未签到

723

主题

6382

帖子

0

超级版主

Rank: 8Rank: 8

积分
25450
最后登录
2025-9-4
发表于 2019-3-7 10:05:40 | 显示全部楼层
shuxmpx123 发表于 2019-3-6 15:33
好的,,感谢, 我现在是直接关闭,然后打开之前调用 lin_goto_idle_state, 我看了初始化函数 lin_lld_u ...

不客气,后续有问题,欢迎继续发帖交流!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条

Archiver|手机版|小黑屋|恩智浦技术社区

GMT+8, 2025-9-6 19:42 , Processed in 0.105156 second(s), 30 queries , MemCache On.

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.

快速回复 返回顶部 返回列表