


更换板子,先在在STM32F4上弄。
直接从硬件弄起太麻烦了。不利于了解OS,毕竟这次活动OS是关键。
我要利用这次活动提高直接使用OS的水平。
还有就是,那一大堆东西:开发板,仿真器,电源,串口线 桌子上没地方堆了




实验13:中断处理
中断处理是一个比较有意思的东西。uTenux的中断处理包括了处理外部中断、CPU异常等。他是OS中任务无关部分。因此,当中断到来的时候OS会停止任务调度,不会发生任务切换。直到程序从中断中返回。
uTenux的中断处理部分API如下:
1、定义中断处理程序
ER ercd= tk_def_int(UINT dintno,T_DINT* pk_dint);
这个函数定义一个中断定义编号为dtintno的中断处理程序,并允许中断处理程序运行。
中断定义编号是0-255的,比如Cortex-M3中NMI就是2,UASRT1中断就是44,USART2中断就是45、USART3中断就是46.这些可以查ST的Datasheet得到。uTenux中,没有强制将中断处理程序定义成指定的函数,用户可以手动添加。对于外设来说,ST的宏定义是0-240的,使用tk_def_int时需要加上16。
pk_dint是中断处理程序的定义,其定义结构体如下:
typedef struct t_dint {
ATR intatr; /* 处理程序属性 */
FP inthdr; /* 中断处理函数入口地址 */
} T_DINT;
2、从中断处理程序中返回
void tk_ret_int();
当处理程序正在运行时,由中断处理程序所调用的系统调用并不会产生分派;相反,分派将会被延迟到调用tk_ret_int来终止中断处理程序的处理以后(分派延迟)。因此,tk_ret_int会导致对所有在中断处理程序运行期间所发布的分派请求进行处理。
【实验描述】
本次实验在市里工程的基础上完成。打开了串口3的接收中断,并使用OS的功能来完成中断的接收和处理。
1、我重写了usart3的初始化函数,使用了我熟悉的库函数操作。
2、设置NVIC,初始化串口3的中断
3、使用tk_def_int定义中断处理函数。
4、在中断处理函数中通过串口向主机消息,表明已经进入了中断。
【实验代码和输出】
1、串口3初始化代码:
void uart3_init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1ENR_USART3EN,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOC,&GPIO_InitStructure);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource10,GPIO_AF_USART3);
GPIO_PinAFConfig(GPIOC,GPIO_PinSource11,GPIO_AF_USART3);
USART_InitStructure.USART_BaudRate = 115200;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART3,&USART_InitStructure);
USART_ITConfig(USART3,USART_IT_RXNE,ENABLE);
USART_Cmd(USART3,ENABLE);
return;
}
2、NVIC设置代码:
void NVIC_Config(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组
//使能USART3中断
NVIC_IniteStructure.NVIC_IRQChannel = USART3_IRQn;
NVIC_IniteStructure.NVIC_IRQChannelPreemptionPriority = 0x01;
NVIC_IniteStructure.NVIC_IRQChannelSubPriority = 0x02;
NVIC_IniteStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_IniteStructure);
}
3、中断处理代码
#include "IntSample.h"
void Usart3Handler(UINT dintno);
EXPORT ER IntSample( void )
{
UINT i;
ER ercd;
UINT intsts;
T_DINT dint;
#if (USE_DBGSPT && USE_HOOK_TRACE)
TD_HINT hint;
#endif
DI(intsts);//屏蔽所有中断
dint.intatr=TA_HLNG;
dint.inthdr=Usart3Handler;//IntHandler;
ercd=tk_def_int((UINT)DINTNO(USART3_IRQn),&dint); //注册串口3中断
EI(intsts);//使能所有中断
while(1);
}
void Usart3Handler(UINT dintno)
{
B c;
USART_ClearFlag(USART3,USART_FLAG_RXNE);//清除中断标志
tm_putstring((UB*)"this is in usart 3 handler.\n");
tk_ret_int();
}
【输出】
需要使用串口软件向MCU发送数据才能显示
----------------------------------------------------
micro Tenux Version 1.6.00(build 0180)
Supported MCU is ST STM32F407VG
Copyright(c) 2008-2013 by Dalian uLoong Co.,Ltd.
----------------------------------------------------
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
this is in usart 3 handler.
【疑问】
中断时候的寄存器保存是在那里进行的?我的M4板子,如果开启了FPU功能,还需要手动添加寄存器保存处理。这个怎样自己添加?



解决链接时候的六个警告:
1、分散加载文件中的四个警告
需要在分散加载文件中,将空的区域使用EMPTY属性标识,说明这个空间是预留的。这样编译器就不会警告了
EMPTY 属性,i就是告诉链接器这是我要保留一个空白内存块,你别管了。修改后的sct文件如下:
LOAD_INTERFLASHROM 0x08000000 0x00100000 { ; load region size_region
EXEC_INTERROM 0x08000000 0x00100000 { ; load address = execution address
* (.vector,+First) ; 1024k
*(InRoot$$Sections)
.ANY (+RO)
}
EXEC_VECTORRAM 0x20000000 EMPTY 0x00000400 { ; vector table region in ram
} ; 1k
EXEC_BSSDATARAM 0x20000400 0x00001c00 { ; zi and rw data region in ram
.ANY (+RW +ZI)
} ; 7k
EXEC_SYSTEMRAM 0x20002000 EMPTY 0x00018000 { ; ut/kernel management region
} ; 100k
EXEC_USERRAM 0x2001b000 EMPTY 0x00001000 { ; user manual region in ram
} ; 4k
EXEC_STACKRAM 0x2001c000 EMPTY 0x00000000 { ; default stack top
} ; 0k
ARM_LIB_HEAP 0x2001A000 EMPTY 0x500 ; 这是为了使用printf之类的系统库设置的
{
}
ARM_LIB_STACK 0x2001A500 EMPTY 0x500
{
}
} ; sum: 112k
2、解决链接时候的警告
警告1、.\out\kernel-rom.axf: Warning: L6306W: '~PRES8 (The user did not require code to preserve 8-byte data objects)' section knl_dispatch.o(.text) should not use the address of 'REQ8 (Code was permitted to depend on the 8-byte aligment of 8-byte data items)' function knl_power_low.
警告2、.\out\kernel-rom.axf: Warning: L6306W: '~PRES8 (The user did not require code to preserve 8-byte data objects)' section knl_int.o(.text) should not use the address of 'REQ8 (Code was permitted to depend on the 8-byte aligment of 8-byte data items)' function knl_timer_handler.
解决这两个警告,参考http://www.keil.com/support/docs/3268.htm
注意这个即可:All C code generated by the RealView compiler assumes that stack allocation is aligned on 8-byte boundaries. You must ensure that the assembler interrupt handler has an 8-byte aligned stack by specifying the PRESERVE8 directive at the beginning of your assembly file.
于是我在发出警告的两个文件里边,.text段之前加了PRESERVE8,警告就消除了
参考上边的一段红字,PRESERVE8这个关键字用来声明字节对齐的。声明之后,链接器就不会警告这里没有对齐了。
于是在knl_int.s和knl_dispatch中的所有.text段前面加上PRESERVE8关键字,警告就消除了。
格式是这样的:
PRESERVE8
AREA |.text|,CODE,READONLY
THUMB
GLOBAL Csym(enaint) [CODE]
。。。。。。。。。。。。。。。。
回复
有奖活动 | |
---|---|
硬核工程师专属补给计划——填盲盒 | |
“我踩过的那些坑”主题活动——第002期 | |
【EEPW电子工程师创研计划】技术变现通道已开启~ | |
发原创文章 【每月瓜分千元赏金 凭实力攒钱买好礼~】 | |
【EEPW在线】E起听工程师的声音! | |
高校联络员开始招募啦!有惊喜!! | |
【工程师专属福利】每天30秒,积分轻松拿!EEPW宠粉打卡计划启动! | |
送您一块开发板,2025年“我要开发板活动”又开始了! |