こんにちは。NoMaYです。CC-RX用プロジェクトのFITのBSPモジュールとGUNRX用プロジェクトのスマートコンフィグレータのBSPモジュールを比較していて気付いたのですが、この書き換えは元のコードの意図を全く理解していないですよね、、、CC-RX用プロジェクトのFITのBSPモジュールのr_bsp\mcu\rx65n\locking.c
bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock){#if BSP_CFG_USER_LOCKING_ENABLED == 0 bool ret = false; /* Variable used in trying to acquire lock. Using the xchg instruction makes this atomic */ int32_t is_locked = true; /* This example uses the RX MCU's atomic xchg() instruction. plock->lock is the lock we are trying to reserve. The way this works is that 'is_locked' gets the value of the plock->lock and plock->lock gets the value of 'is_locked' which we just set to 'true'. Basically this is an atomic 'swap' command. If the lock had not yet been reserved then its value would be 'false' and after the xchg() instruction finished 'is_locked' would have 'false'. If it had already been reserved then 'is_locked' would have 'true' after the xchg() instruction. Since plock->lock was already 'true' and we just set it back to 'true' everything is ok. To see if we reserved the lock we just need to check the value of 'is_locked' after this instruction finishes. */ /* Try to acquire semaphore to obtain lock */ xchg(&is_locked, &plock->lock); /* Check to see if semaphore was successfully taken */ if (is_locked == false) { /* Lock obtained, return success. */ ret = true; } else { /* Lock was not obtained, another task already has it. */ } return ret; #else /* User is going to handle the locking themselves. */ return BSP_CFG_USER_LOCKING_SW_LOCK_FUNCTION(plock);#endif} /* End of function R_BSP_SoftwareLock() */
生成されたコード(最適化無しでの例)
bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock) ADD #0FFFFFFF0H, R0 MOV.L R1, 0CH[R0] bool ret = false; MOV.B #00H, 03H[R0] int32_t is_locked = true; MOV.L #00000001H, 04H[R0] xchg(&is_locked, &plock->lock); ← 第2引数がxchg命令のメモリオペランド側となる仕様の組み込み関数 MOV.L 0CH[R0], R1 MOV.L 04H[R0], R2 XCHG [R1].L, R2 MOV.L R2, 04H[R0] 以後省略
GUNRX用プロジェクトのスマートコンフィグレータのBSPのBSPモジュールのr_bsp\mcu\rx65n\locking.c
bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock){#if BSP_CFG_USER_LOCKING_ENABLED == 0 bool ret = false; /* Variable used in trying to acquire lock. Using the xchg instruction makes this atomic */ int32_t is_locked = true; /* This example uses the RX MCU's atomic xchg() instruction. plock->lock is the lock we are trying to reserve. The way this works is that 'is_locked' gets the value of the plock->lock and plock->lock gets the value of 'is_locked' which we just set to 'true'. Basically this is an atomic 'swap' command. If the lock had not yet been reserved then its value would be 'false' and after the xchg() instruction finished 'is_locked' would have 'false'. If it had already been reserved then 'is_locked' would have 'true' after the xchg() instruction. Since plock->lock was already 'true' and we just set it back to 'true' everything is ok. To see if we reserved the lock we just need to check the value of 'is_locked' after this instruction finishes. */ /* Try to acquire semaphore to obtain lock */ int32_t tmp; tmp = is_locked; is_locked = plock->lock; plock->lock = tmp; /* Check to see if semaphore was successfully taken */ if (is_locked == false) { /* Lock obtained, return success. */ ret = true; } else { /* Lock was not obtained, another task already has it. */ } return ret; #else /* User is going to handle the locking themselves. */ return BSP_CFG_USER_LOCKING_SW_LOCK_FUNCTION(plock);#endif} /* End of function R_BSP_SoftwareLock() */
bool R_BSP_SoftwareLock (BSP_CFG_USER_LOCKING_TYPE * const plock) push.l r6 add #-16, r0, r6 mov.L r6, r0 mov.L r1, 12[r6] bool ret = false; mov.B #0, [r6] int32_t is_locked = true; mov.L #1, 4[r6] int32_t tmp; tmp = is_locked; mov.L 4[r6], r5 mov.L r5, 8[r6] is_locked = plock->lock; mov.L 12[r6], r5 mov.L [r5], r5 mov.L r5, 4[r6] plock->lock = tmp; mov.L 12[r6], r5 mov.L 8[r6], r4 mov.L r4, [r5] 以後省略
[関連リンク]
RXファミリ RXv2命令セットアーキテクチャ ユーザーズマニュアル ソフトウェア編www.renesas.com/ja-jp/search/keyword-search.html#q=R01US0071CC-RXコンパイラ ユーザーズマニュアルwww.renesas.com/ja-jp/search/keyword-search.html#q=R20UT3248
鈴木さん、こんにちは。NoMaYです。元のコードに非常に長いコメント(下記)が存在することから察して欲しいと思うのですが、この箇所は、ただ単にデータ交換を行うコードでは無い、ということなのです。
This example uses the RX MCU's atomic xchg() instruction. plock->lock is the lock we are trying to reserve. The way this works is that 'is_locked' gets the value of the plock->lock and plock->lock gets the value of 'is_locked' which we just set to 'true'. Basically this is an atomic 'swap' command. If the lock had not yet beenreserved then its value would be 'false' and after the xchg() instruction finished 'is_locked' would have 'false'. If it had already been reserved then 'is_locked' would have 'true' after the xchg() instruction. Since plock->lock was already 'true' and we just set it back to 'true' everything is ok. To see if we reserved the lockwe just need to check the value of 'is_locked' after this instruction finishes.
元のコードに書かれている以下のコメントから分かる通り、セマフォのロックを行うコード、なのです。
Variable used in trying to acquire lock. Using the xchg instruction makes this atomic
Try to acquire semaphore to obtain lock
Check to see if semaphore was successfully taken
この件に関しては、Wikipediaの以下のページが理解の一助になると思います。(ちなみに、元のコードの処理と1対1で対応する説明が書かれている訳では無いですので、それなりに、頭を使う必要があります。)en.wikipedia.org/wiki/Semaphore_(programming)ja.wikipedia.org/wiki/セマフォen.wikipedia.org/wiki/Test-and-setja.wikipedia.org/wiki/テスト・アンド・セット以下、そこからの画面コピーです。