バックナンバーはこちら。
https://www.simulationroom999.com/blog/model-based-of-minimum-2-backnumber/
はじめに
AUTOSAR-XCPをPCシミュレーションするにあたっていくつかのWindowsAPIが必要となる。
そのためにはwindows.hをincludeすることになるが、これが他の定義と衝突することがある。
よって、stub.cでWindowsAPIのラップ関数を定義することで回避する。
あとはCanIf関連の辻褄合わせが必要であるが、
ここはmain.cでうまくやっているらしいので、それを確認する。
登場人物
博識フクロウのフクさん
イラストACにて公開の「kino_k」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=iKciwKA9&area=1
エンジニア歴8年の太郎くん
イラストACにて公開の「しのみ」さんのイラストを使用しています。
https://www.ac-illust.com/main/profile.php?id=uCKphAW2&area=1
main.c
前回の話だとmain.cでいろいろ辻褄合わせをしてるようなこと言ってたけど、どんな感じになってるの?
これもまずはソースコードを貼ってしまおう。
int cycle_cnt;
extern Xcp_ConfigType g_DefaultConfig;
Std_ReturnType _CanIf_Transmit(PduIdType CanTxPduId, const PduInfoType *PduInfoPtr)
{
size_t i;
vcanMessage msg = { 0 };
msg.Dlc = PduInfoPtr->SduLength;
int fd = 0;
#ifdef CANFD_SUPPORT
fd = 1;
#endif
if (CanTxPduId == 0) {
msg.Id = 2;
}
msg.Ext = VCAN_ID_STD;
for (i = 0U; i < PduInfoPtr->SduLength; i++) {
msg.Data[i] = PduInfoPtr->SduDataPtr[i];
}
viratualCanSend(pVcanHandle, &msg, fd);
return(BUFREQ_OK);
}
int rx_interrupt(void *param, vcanMessage* msg)
{
_WaitForSigleObject(hMutex, -1);
// for CAN-FD
static const uint8 cantp_canfd_dlc_snd_table[] = {
0U, 1U, 2U, 3U, 4U, 5U, 6U, 7U,
8U, 12U, 16U, 20U, 24U, 32U, 48U, 64U,
};
XcpInfo.SduDataPtr = msg->Data;
XcpInfo.SduLength = cantp_canfd_dlc_snd_table[msg->Dlc];
if (msg->Id == 1) {
Xcp_CanIfRxIndication(1, &XcpInfo);
}
_ReleaseMutex(hMutex);
return 0;
}
int tx_interrupt(void *param, vcanMessage* msg)
{
return 0;
}
int err_interrupt(void *param, vcanMessage* msg)
{
return 0;
}
void main_handler()
{
_WaitForSigleObject(hMutex, -1);
ecu_t1ms_job();
if (cycle_cnt % 10 == 0) {
ecu_t10ms_job();
}
if (cycle_cnt % 100 == 0) {
ecu_t100ms_job();
}
if (cycle_cnt % 200 == 0) {
ecu_t200ms_job();
}
Xcp_MainFunction();
Xcp_MainFunction_Channel(3);
if (cycle_cnt % 10 == 0) {
Xcp_MainFunction_Channel(1);
}
if (cycle_cnt % 100 == 0){
Xcp_MainFunction_Channel(2);
}
cycle_cnt++;
_ReleaseMutex(hMutex);
}
void XcpStandaloneLock()
{
_WaitForSigleObject(hMutex, -1);
}
void XcpStandaloneUnlock()
{
_ReleaseMutex(hMutex);
}
void Det_ReportError(uint16 ModuleId, uint8 InstanceId, uint8 ApiId, uint8 ErrorId)
{
printf("Det_ReportError ModuleId=%d, InstanceId=%d, ApiId=%d, ErrorId=%d \n", ModuleId, InstanceId, ApiId, ErrorId);
}
int main()
{
syslog(LOG_NOTICE, "=== MainTask ===");
hMutex = _CreateMutex(NULL_PTR, FALSE, (char*)NULL_PTR);
_timeBeginPeriod(1);
pVcanHandle = viratualCanInit(0, rx_interrupt, tx_interrupt, err_interrupt, 0, "autosar-xcp", 1);
viratualCanConfig(pVcanHandle, 500000, 2000000);
viratualCanStart(pVcanHandle);
syslog(LOG_NOTICE, "== XcpTp_Init ==");
ecu_init();
Xcp_Init(&g_DefaultConfig);
_Sleep(1);
setcallback(main_handler);
return 0;
}
main.c解説
これは、まぁまぁ規模が大きいなー。
パッと見た感じだと
送信関数と送信完了割り込み、受信割り込み、エラー割り込みを定義してる感じか。
これがCanIfの辻褄合わせのところだね。
あとはmain_handlerでecu内部処理の周期を定義して、
同じようにXCP関連のイベントチャンネル毎の処理を定義してるのか。
XcpStandaloneLock、XcpStandaloneUnLockは
AUTOSAR-XCP内から呼ばれてる排他同期用関数ってところだね。
Det_ReportErrorもAUTOSAR-XCP内から呼ばれるエラー通知関数かな。
最後にmain関数がプログラム起動時の関数でいろいろ初期化している。
ってところか。
大正解だ!
よっしゃ!
そして現在の状態は?
これでやっとビルドが通った。って状態になる。
まだ動かないのか・・・。
あとはAUTOSAR-XCPのコンフィグレーションをしないといけないかな。
まぁこれもヘッダ内のdefine定義する部分と内部のデータ構造を定義する部分にわかれるんだけど。
まだまだ先は長そうだな・・・。
まとめ
まとめだよ。
- CanIfとかAUTOSAR-XCPから呼び出される関数群の辻褄合わせをmain.cで実施。
- 送信関数と送信完了割り込み、受信割り込み、エラー割り込み。
- 排他制御関数。
- エラー通知関数。
- main関数で初期化処理関連を実施。
- これでやっとビルドが通った状態となる。
バックナンバーはこちら。
コメント