0

关于投票
为啥有的要声明为静态?

原帖讨论: http://bbs.21ic.com/club/bbs/list.asp?boardid=42&t=2853557

phoenixmy 发表于 2008-2-9 12:47 ZLG-MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

5楼: 为啥有的要声明为静态?



    static void HibernateISR(void);//必须声明为静态函数!!!
    static void SysTickISR(void);//必须声明为静态函数!!!

hotpower 发表于 2008-2-10 00:35 ZLG-MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

7楼: 不声明为静态函数就得不到类的实际地址

类的声明和变量的类型声明实际是一样的,它们并不实际存在.
只有在定义并分配空间后,才能得到实际的物理地址.

由于类的成员变量的备份可能有许多,而类的成员函数实际是共享的.
所以类的成员函数的地址应该是唯一的.

声明为静态函数实际和生存期有关,不声明为静态函数,编译器将找不到
成员函数的物理地址.

基于以上的理解,类的(静态)成员函数做中断函数后,由于类的成员变量的备份可能有许多,

所以IAR要求访问时需要:实际类名称.类成员(变量/函数),想来也真是有道理的~~~

特别是: 实际类名称.类成员变量.

不过再饶着站在GCC的立场上想: 类的(静态)成员函数做中断函数肯定是唯一的.
所以指明类的实际名称是多余的~~~

总之两者都各有自己的道理~~~所以编程者就遵守各自的约定好了~~~

系统分类: ARM
用户分类: LM菜鸟实习
标签: 无标签
来源: 整理
发表评论 阅读全文(361) | 回复(0)

0

关于投票
IAR环境下LM中C++类成员函数做中断函数源码下载
hotpower 发表于 2008-2-9 13:00 ZLG-MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

6楼: IAR环境下LM中C++类成员函数做中断函数源码下载

注意本例程用LM LINK下载程序后应该将LM LINK去掉!!!

进入休眠要先按Key1不放再长压Key4进入休眠状态!!!

这样按WAKE才能从休眠中唤醒~~~

菜农 HotPower@126.com  2008.2.9 4:08 于雁塔村菜地



点击下载程序例程源码

系统分类: ARM
用户分类: LM菜鸟实习
标签: 无标签
来源: 原创
发表评论 阅读全文(343) | 回复(0)

0

关于投票
IAR FOR ARM中C++类成员函数做中断函数的三个主要步骤

原帖出处: http://bbs.21ic.com/club/bbs/list.asp?boardid=42&t=2853557

hotpower 发表于 2008-2-9 12:19 ZLG-MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

4楼: 类成员函数做中断函数的三个主要步骤

1.在类中声明ISP()
class SystemObj
{
public:
//................
//类成员函数做中断函数
    static void HibernateISR(void);//必须声明为静态函数!!!
    static void SysTickISR(void);//必须声明为静态函数!!!
public:
    volatile unsigned int RamTest;
    union
    {
        volatile unsigned char WorkFlag;
        struct
        {
            unsigned char Watchdog:         1;//允许喂狗
            unsigned char SysTickFlag:      1;//节拍中断
            unsigned char MainLoopFlag:     1;//主循环运行
            unsigned char MainWatchdog:     1;//主循环喂狗
        };
    };
};

class UartObj {
public:
//.........
//类成员函数做中断函数
    static void UART0ISR(void);//必须声明为静态函数!!!
};

2.构造类成员函数
//5mS定时中断服务程序(类成员函数做中断函数)
//static//此处不能加static!!!
//类成员变量必须指明实际的类!!!(System.MainWatchdog 不能写成MainWatchdog)
void SystemObj::SysTickISR(void)
{
    Keyboard.Exec();//"零耗时键盘"消抖及运行命令
    if (System.Watchdog)//允许喂狗
    {
      if (!System.MainWatchdog)//中断喂狗论
        {
            if (!System.SysTickFlag && System.MainLoopFlag)//主程序在工作
            {
                WatchdogIntClear(WATCHDOG_BASE);//真正的硬件喂狗!!!
            }
        }
    }
    System.SysTickFlag = true;//通知主循环节拍中断正常工作
}

//休眠激活中断服务程序(类成员函数做中断函数)
//static//此处不能加static!!!
void SystemObj::HibernateISR(void)
{
   HWREG(HIB_CTL) &= ~ HIB_CTL_HIBREQ;
   HibernateIntClear(HIBERNATE_INT_PIN_WAKE    | HIBERNATE_INT_LOW_BAT |
                 HIBERNATE_INT_RTC_MATCH_0 | HIBERNATE_INT_RTC_MATCH_1);
}

//串口中断服务程序(类成员函数做中断函数)
//static//此处不能加static!!!
void UartObj::UART0ISR(void)
{

    unsigned long ulStatus;
    ulStatus = UARTIntStatus(UART0_BASE, true);
    UARTIntClear(UART0_BASE, ulStatus);
    while(UARTCharsAvail(UART0_BASE))
    {
        UARTCharPutNonBlocking(UART0_BASE, UARTCharGetNonBlocking(UART0_BASE));
    }
}

3.在startup.c内的中断向量表内填写需要中断的类成员函数地址
__root static const uVectorEntry g_pfnVectors[] @ "INTVEC" =
{
    { .ulPtr = __sfe( "CSTACK" ) },
    __program_start,                        // The reset handler
//    ResetISR,                             // The reset handler
    NmiSR,                                  // The NMI handler
    FaultISR,                               // The hard fault handler
    IntDefaultHandler,                      // The MPU fault handler
    IntDefaultHandler,                      // The bus fault handler
    IntDefaultHandler,                      // The usage fault handler
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    0,                                      // Reserved
    IntDefaultHandler,                      // SVCall handler
    IntDefaultHandler,                      // Debug monitor handler
    0,                                      // Reserved
    IntDefaultHandler,                      // The PendSV handler
    &SystemObj::SysTickISR,                 // The SysTick handler
//不能用下列写法
//    &System.SysTickISR,                     // The SysTick handler
//...................
    &UartObj::UART0ISR,                     // UART0 Rx and Tx
//不能用下列写法
//    &Uart.UART0ISR,                         // UART0 Rx and Tx
    IntDefaultHandler,                      // UART1 Rx and Tx
//...................
    IntDefaultHandler,                      // Ethernet
    &SystemObj::HibernateISR                // Hibernate
//不能用下列写法
//    &System.HibernateISR                    // Hibernate
};


可以看出IAR实在不如GCC~~~不过还是能过得去的~~~

请看:
//static//此处不能加static!!!
//类成员变量必须指明实际的类!!!(System.MainWatchdog 不能写成MainWatchdog)
void SystemObj::SysTickISR(void)
{
    Keyboard.Exec();//"零耗时键盘"消抖及运行命令
    if (System.Watchdog)//允许喂狗
//...................

哈哈~~~看看gcc的2个步骤吧(它隐含了中断向量表)
1.在类中声明ISP()
class AdcObj {
public:
//................
//类成员函数做中断函数
  void SIG_ADC(void)  __attribute__ ((signal));
private:
  unsigned char AdcNum;//加volatile将增大空间72个字节
  unsigned char AdcCount;//加volatile将增大空间4个字节
  volatile unsigned int AdcSum[8];//不改变
  unsigned int AdcMax[8];//加volatile将增大空间4个字节
  volatile unsigned int AdcMin[8];//不改变
};

2.构造类成员函数
void AdcObj::SIG_ADC(void)
{
unsigned int adcval;
  adcval = ADC & 0x3ff;//取ADC转换电压,并保存
  SetAdcChNum(AdcNum + 1);//设置新通道
/*-----------------------------------------------------------
  求最大值,最小值,累加和(0,5不用侧)
------------------------------------------------------------*/
  if (AdcNum & 1) {//偶数不测试
    AdcSum[AdcNum] += adcval;//存累加和
    if (adcval > AdcMax[AdcNum]) {
      AdcMax[AdcNum] = adcval;//最大值
    }
    if (adcval < AdcMin[AdcNum]) {
      AdcMin[AdcNum] = adcval;//存最小值
    }
  }
//...........................
}

可以看出gcc才是最完美的类成员函数做中断函数~~~
而IAR的类成员函数做中断函数后不能访问自己类的其他成员实在倒塌~~~

哈哈~~~估计是菜农还没彻底将其倒塌...估计还要求助TestCode同志~~~

系统分类: ARM
用户分类: LM菜鸟实习
标签: 无标签
来源: 原创
发表评论 阅读全文(315) | 回复(0)

0

关于投票
不抛弃不放弃---类成员函数终成中断函数(发帖自贺)

原帖: http://bbs.21ic.com/club/bbs/list.asp?boardid=42&page=1&t=2853557

hotpower 发表于 2008-2-9 04:14 ZLG-MCU ←返回版面 按此察看该网友的资料 按此把文章加入收藏夹 按此编辑本帖

楼主: 不抛弃不放弃---类成员函数终成中断函数(发帖自贺)

哈哈~~~终于了却了在Cortex M3上的C++类成员函数做中断函数的心愿~~~

又是一个4点钟~~~菜农"跳出黄河"的时间此生几乎都在后半夜...

C++之路----全扫荡完了...发帖自贺

菜农HotPower@126.com  2008.2.9 4:08 于西安大雁塔菜地

系统分类: ARM
用户分类: LM菜鸟实习
标签: 无标签
来源: 原创
发表评论 阅读全文(284) | 回复(0)

0

关于投票
LM菜鸟"驳中断不能喂狗"的"经典谬论"之C++演示程序

本程序主要实验目的:

1.时钟节拍中断
  主要体验Cortex-M3的SysTick及其中断.
2."零耗时键盘"的基本建立
  KEY1~KEY4. 只建立了放键,短压和长压3个事件。
  可像钢琴一样乱弹看LED3~LED6的变化及"并行任务"的实现,
  长压键蜂鸣器发声直到放键为止。
  这里只涉及了最基本的应用,回调钩子等技术未在本例中使用.
  所以它还不能称之为"基于零耗时键盘的OS",不过有人明白如何实现~~~
3.复位键做"键盘"
  不断电每按一次复位键LED1~LED2将交替亮灭。
4.再现C++类成员函数指针及在键盘命令表上的典型应用.

有人应该明白为什么键盘不用外部中断,为什么键盘要"扫而不描"的道理。

菜农 HotPower@126.com  2008.1.25 2:48 于雁塔村菜地

LM菜鸟"驳中断不能喂狗"的"经典谬论"之C++演示程序

本例程主要在"零耗时键盘"裸奔程序的基础上新增加4个内容

1.增加了串口收发例程。(未按菜农之思路)

2.增加了休眠WAKE键唤醒功能.
  注意相关的跳线. 先按Key1再长压Key4-->自毁~~~必须按WAKE键唤醒。

3.可先按Key2再Key1交替禁止或允许喂狗切换。
  注意不喂狗时,喂狗超时将使系统复位,LED1~LED2将交替亮灭

4.可先按Key3再Key4切换中断喂狗或主循环喂狗方式.
  本例默认中断喂狗方式,当先按Key3再Key4切换到主循环喂狗时。
  为论证故意关掉了总中断!!!蜂鸣器长叫~~~
  主程序中的主循环"正常工作",由于只能在中断中关闭蜂鸣器。
  所以唯一的办法就是按复位键~~~按晚复位键耳朵吵坏了别怪俺~~~

菜农 HotPower@126.com  2008.1.26 4:18 于雁塔村菜地


点击下载源程序压缩包LMCPPDEMO.rar

签名:

●█〓██▄▄▄▄▄▄ ●●●●●●→ ''''╭WWWW╮
▄▅██████▅▄▃▂ 传播非典灌水四方 ( ●_●)
██████████████ '''',,,;,;,;'''/▇\''
◥⊙▲⊙▲⊙▲⊙▲⊙▲⊙▲◤ 俺的地盘俺做主/MMMM\
菜农浇灌的水田


俺的地盘俺做主
系统分类: ARM
用户分类: LM菜鸟实习
标签: 无标签
来源: 原创
发表评论 阅读全文(557) | 回复(4)