This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] 编译器/TM4C123GH6PGE:"friend&quot的语言在哪里描述;为什么私有数据不可访问?

Guru**** 2528720 points
Other Parts Discussed in Thread: TM4C123GH6PGE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/621820/compiler-tm4c123gh6pge-where-is-the-language-of-friend-described-why-is-private-data-not-accessible

部件号:TM4C123GH6PGE

工具/软件:TI C/C++编译器

手续:
--------

部件号:TM4C123GH6PGR
使用Tiva123G启动板
编译器版本:TI v 16.9 .4.LTS

问题:
--------
我已将TIVA驱动程序lib组件ca.h/h移植到C++环境中,并且99.99 % 运行良好。 我的意思是,中断处理程序被调用,消息被处理,我可以像multi_rx/multi_tx示例的原始TIVA示例一样发送/接收。 我偶然遇到的是为什么向CAN类声明中断处理程序为“朋友”不允许访问私有变量。将变量“hasNewMsg”声明为公共成员是可以正常工作的,但不允许私有或受保护的访问。

我确实搜索了16.9 v.4.LTS的编译器版本以及以下文档:

http://processors.wiki.ti.com/index.php/C%2B%2B_Support_in_TI_Compilers

http://www.caravan.net/ec2plus/

但对朋友的实施没有任何了解。 我在下面简要介绍了我要做的事情。 我对代码中的简洁的分类。 我不想用太多无关信息污染帖子。

我想说,我没有ISO标准(现在正在寻求下载),我在Chris Kormanyous的“实时C++”中认为所有成员都应该是私有的,受保护的和公开的。 我意识到Chris正在使用GCC,他可能不正确,这就是为什么我要在TI文档中寻找正确的参考。

另外,这可能有点偏离主题,但如何将CCS V7编译器升级到最新的17.6 (vv STS.0.STS)编译器。

问题背景:
-----------------------

使用一个类,可以:

类可以

私人:
...
   UINT32_t有新消息;
   朋友
   void interrupt CAN0InterruptHandler();
...
公开:
...

};

中断处理程序:

外部"C"


CAN CAN:
无效
CAN0IntHandler (void)

...
       CAN.HASNewMsg = 1;
...

}
}

感谢您耐心阅读长帖子,以及您可以提供的任何帮助。


戴夫

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    首先,函数的名称不一致;是"Int"还是"Interrupt"?  其次,要“朋友”使用外部"C"函数,您需要在类定义之前建立外部"C"函数的原型,如下所示:

    #include <stdint.h>
    
    extern "C" void中断CAN0IntHandler(void);
    
    类可以
    {
    private:
    UINT32_t有新消息;
    Friend void中断CAN0IntHandler(void);
    };
    
    Can;
    
    extern "C"{
    void中断CAN0IntHandler (void)
    {
    CAN.HASNewMsg =1;
    }
    }
    
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的回复。 在您的初始注释中,实际类型为void。 编译器手册(第5.6 .2节)提到,__interrupt或interrupt用于将函数视为中断函数。 但是,TIVA示例不会执行此操作,而是使用void。 无论如何,我应该将interrupt关键字删掉,因为代码编译并运行时使用了“void CAN0Handler(void)"或“void interrupt CAN0Handler()",而不是"interrupt CAN0Handler()"或"__CAN0Handler()。 这是我一直在研究的另一个问题,不是我尝试"朋友"的变量访问错误的原因。

    我确实在代码中放置了"extern "C" void interrupt CAN0IntHandler(void)",但这也不能解决访问错误。 我不认为会这样,因为我可以访问CAN类的公共方法和数据,但不能访问私有或受保护的方法或数据。 这就是为什么我要寻找描述编译如何实现Friend关键字的文档的原因。 我已将与此讨论相关的代码复制到下面。 请注意,大多数CAN类成员都是从TIVA can.h文件中提取的,其中c++文件在函数前面加上CAN:。 它不是最佳设计,但它是班级的起点。

    所以,我仍在寻找编译器为朋友所遵循的“规则”。 Wiki指向的链接(www.caravan.net/ec2plus

    --这是文件CANIntHandler.cpp
    
    中的CAN0Interrupt处理程序void
    CAN0IntHandler(void){
    
    uINT32_t ui32状态;
    uINT32_t uiNewMsgNum;
    uINT32_t uiNewMsgMask;
    
    //获取CAN状态
    ui32Status = HWREG (CAN0_BASE + CAN_O_STS);
    
    //检查RXOK或TXOK状态
    如果(ui32Status和CAN_STS_RXOK)
    {
    //将CAN新数据1和新数据2寄存器连接到一个寄存器中
    //用作掩码的单词。
    uiNewMsgMask =(HWREG (CAN0_BASE + CAN_O_NWDA2)<16)| HWREG (CAN0_BASE + CAN_O_NWDA1);
    
    //删除未配置的消息位。 不确定这是否必要。
    uiNewMsgMask &=(HWREG (CAN0_BASE + CAN_O_MSG2VAL)<16)| HWREG (CAN0_BASE + CAN_O_MSG1VAL);
    
    IF (uiNewMsgMask)
    {
    //复制新邮件。 这也会清除
    // RX中断。
    CAN.receiveNewMessages(uiNewMsgMask);
    CAN.HASNewMsg =1;
    }
    }}-->
    
    
    以下是CAN类定义
    
    外部"C" void中断CAN0IntHandler(void);
    
    类可以
    {
    私有:
    uINT32_t速度;
    void CANInit();
    UINT32_t m_CANBase;
    tCANMsgObject m_CANRXMessages[32];
    UINT8_t m_RxMsgData[32][8];
    Friend void CAN0InterruptHandler();
    UINT32_t有新消息;
    
    公共:
    CAN(){}
    CAN(UINT32_t ui32Base, UINT32_t gpioPeripheral,UINT32_t gpioPortBase, UINT32_t rxGPIOPinMux,UINT32_t txGPIOPinMux, UINT32_t rxGPIOPin,UINT32_t txGPIOPin,UINT32_t canPeripheral,UINT32_t bitrate,UINT32_t canInterrupt);
    UINT32_t注册器NewMsgCallback(CBK_CAN_MSG newMessageCallbackFunction);
    void receiveNewMessages(UINT32_t newMsgMask);
    静态空调用新讯息函数(UINT32_t newMsgMask);
    void testCallbackFunction(){ CallNewMessageFunction(1);};
    静态CAN* getInstance (void);
    静态布尔_CANBaseValid (UINT32_t ui32Base);
    静态uint_fast8_t _CANIntNumberGet (UINT32_t ui32Base);
    静态void _CANDataRegWrite(uint8_t *pui8Data, UINT32_t *pui32Register),UINT32_t ui32Size;
    静态void _CANDataRegRead (uint8_t *pui8Data,UINT32_t *pui32Register,UINT32_t ui32Size);
    void CANEnable();
    void CANDisable();
    void CANBitTimingGet (tCANBitClkParms *psClkParms);
    UINT32_t CANBitRateSet (UINT32_t ui32SourceClock, UINT32_t ui32BitRate);
    void CANBitTimingSet(tCANBitClkParms *psClkParms);
    void CANIntRegister(UINT32_t ui32Base, void (*pfnHandler)(void);
    void CANIntUnregister(UINT32_t ui32Base);
    void CANIntEnable(UINT32_t ui32IntFlags);
    void CANIntDisable(UINT32_t ui32IntFlags);
    静态UINT32_t CANIntStatus (UINT32_t ui32Base,tCANIntStsReg eIntStsReg);
    静态void CANIntClear (UINT32_t ui32Base,UINT32_t ui32IntClr);
    void CANRetrySet(bool bAutoRetry);
    Bool CANRetryGet();
    UINT32_t CANStatusGet (tCANStsReg eStatusReg);
    布尔型CANErrCntrGet (UINT32_t *pui32RxCount,UINT32_t *pui32TxCount);
    void CANMessageSet(UINT32_t ui32ObjID, tCANMsgObject *psMsgObject, tMsgObjType eMsgType);
    void CANMessageGet(UINT32_t ui32ObjID, tCANMsgObject *psMsgObject, bool bClrPendingInt);
    void CANMessageClear (UINT32_t ui32ObjID);
    void SendCANMessage(UINT32_t接收器ID, UINT32_t dlen, uint8_t *pui8MsgData);
    uINT32_t getNewMsgMask();
    void clearNewMsgMaskBit(UINT32_t I);
    void PrintCANMessageInfo(tCANMsgObject *psCANMsg);
    };
    
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您错过了一点:您的类可以声明名为CAN0InterruptHandler的Friend函数,该函数在任何地方都没有定义。  此外,您还定义了名为CAN0IntHandler的外部"C"函数,该函数没有相同的名称,因此它是完全不相关的。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    哇! 森林? 树? 啊! 这让人尴尬。 我非常感谢你的帮助和耐心以及眼睛帮助我完成这项工作。 让我抓狂。

    现在,我希望这个请求听起来不会让我感到很不高兴,但是,TI编译器如何实现的最佳参考(即ISO标准98? 2003?) C/C++语言以及如何获取最新更新? www.caravan.net

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    较早版本的TI编译器支持C++98。 较新的版本同时支持C++98和C+03。 C+03主要是C++标准的错误修复版本,因此除了C++98之外,它几乎没有什么功能。 请访问 processors.wiki.ti.com/.../C++_Support_in_TI_Compilers

    语言支持的特定于实现的详细信息(类型大小,纯"char"的无符号性等)在编译器的《编译器用户指南》中进行了介绍。 请访问 processors.wiki.ti.com/.../TI_Compiler_Information

    对编译器的更新通常通过“帮助”菜单下的CCS“检查更新”和“安装新软件”菜单项进行。 我会让其他人提供指向此文档的指针,我没有可用的链接。 (我有一段时间无法联系到办公室。)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    编译器的更新通常通过“帮助”菜单下的CCS“检查更新”和“安装新软件”菜单项进行。 我会让其他人提供指向此文档的指针,我没有可用的链接。 [/引述]

    请参阅 编译器发行版一文

    谢谢,此致,

    -George

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好George。 感谢您的回复。 我使用过Eclipse (CCS)更新,但我认为更新主要针对(长期) LTS版本,因为我尚未看到下载的任何短期(STS)版本。 我正在尝试获取短期(6个月) STS版本以及长期(LTS)版本。 因此,您提供的链接会带来一段视频和文章,介绍如何更好地控制对各种版本的访问,我将阅读/查看这些信息。 我注意到,对于将来关注此问题的任何人来说,Eclipse中的所有来源“可用软件站点”都是选定的,所以这不是问题。

    再次感谢,

    戴夫
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    STS版本在CCS中肯定可用。 不要忘记,您需要使用“安装新软件”菜单项,因为编译器的不同主要版本被视为不同的软件包。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢。 我确实忘记了。 我能够安装最新版本。 再次感谢您的帮助。 现在是

    :)

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这应该是一个简单的按钮...哦,好的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    顺便说一句,我刚刚想到我还可以按下编译器版本下拉框右侧的“更多”按钮。 安装17.6 v.0 STS时,我发现安装的更新在某个点(可能是初始CCS V7安装)没有出现在编译器版本下拉框中。 我猜大部分是STS版本,因为之前的所有条目都是LTS或GCC Linaro。 我想在将来的读者中,我会提到这一点,他们会像我一样寻求想法。