07.Ubuntu下开发STM32--使用串口Part2

16 篇文章 1 订阅

在上一篇Part1的时候,我们说了有个bug,也就是中断向量表的问题。其实这个问题在第4节—在SRAM中运行程序的时候就存在。只不过我们的程序中没有使用中断,也就导致这个bug没有发现。如果我们在上一节的代码中尝试将程序下载到SRAM中运行的时候,也就是make sram,sudo make burns,这样串口只能发送。不能接收。究其原因还是中断惹得祸。

我们使用st-flash工具直接将代码下载到SRAM中,st-flash在下载完之后,会尝试更改pc到Reset_Handler。并运行第一行代码。但是当我们的中断来了之后,该区何处寻找中断向量呢?我们仅仅改了PC的值,并没有改中断向量表的值。也就导致中断来临时,跳转到了错误的中断向量中。(应该是0x0800_0000处中断向量表中对应的位置)

如何更改中断向量表?

更改中断向量表,需要更改SCB->VTOR。关于他的解释请参考《ARM Cortex-M3权威指南》或者网址:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0203hc/Cihdidh2.html 。

img

在system_stm32f30x.c中,有这样的代码:

img

这个文件会根据我们定义的宏来自动设置SCB->VTOR.代码从Flash启动的时候,取消VECT_TAB_SRAM,并且设置VECT_TAB_OFFSET为0。当代码从SRAM中启动的时候,定义VECT_TAB_SRAM,设置VECT_TAB_OFFSET为0x5000(也就是我们代码起始地址相对于0x2000_0000的偏移量)。使用Makefile来定义宏进行版本控制并不简单,但是可以链接不同的文件来达到这个目的。

更改Makefile进行版本控制

拷贝stlib/system_stm32f30x.c到stlib/system_stm32f30x_sram.c。并按照上图更改VECT_TAB_SRAM,VECT_TAB_OFFSET.
修改Makefile如下:

img

img

在修改完Makefile之后,使用make clean,make sram,sudo make burn进行下载,测试之后发现字符已经能够回显。说明成功的进中断。在SRAM中运行代码成功。

修改__io_getchar以适应backspace

在输入的时候,按下键盘的backspace之后,光标往前移动一个字符,并没有在屏幕上删除,类似于插入模式。我们想实际的删除一个字符,需要在屏幕上打印一个空格将之前的字符覆盖。废话少说,看代码:

int __io_getchar(void)
{
    signed char ch;
    while(rbempty(&rb_usart)) continue;
    ch=rbget(&rb_usart);
    switch(ch)
    {
        case '\r':ch='\n';return __io_putchar(ch);
        case 0x1b:ch=' '; return __io_putchar(ch);
        case 0x08:/* backspace in minicom or putty */
        case 0x7F:
            /* earse char in screen(replace with space
             and return the backspace code */
            __io_putchar(ch); __io_putchar(' ');__io_putchar(ch);
            return ch;
        default: return __io_putchar(ch);
    }
   
    /* echo it */
    return __io_putchar(ch);
}
_exit系统调用

从点亮led灯开始,我们就一直添加_exit这个系统调用。关于更加具体的东西并没有详细的说明。
当我们使用exit退出的时候,exit做一些清理工作之后,继续调用_exit_exit的最后一行应该是个死循环,或者产生一个软件复位信号,让程序从头开始执行。exit是需要一个参数的,用于指示系统是不是正常结束。

void _exit(int status)
{
    const char *exit_str="GoodBye!\n";
    const char *tmp=exit_str;
    for(;*tmp!='\0';tmp++)
        __io_putchar(*tmp);
   
    for(;;) continue;
}

但在主函数中,如果使用exit能够正常的调用_exit,但是主函数使用return xxx的时候,并不能调用_exit。如果想让main的返回值传递给_exit,需要更改启动文件。

本次所有的代码都在serial_v4.zip文件中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值