Здесь нам на помощь могут прийти побитовые операции.
Например, если нужно в зависимости от значения какого-либо бита в регистре выставить другой разрешающий бит в другом регистре:
if( бит_в_mask_reg == 0 ) {
установить_бит_того_что_событие_произошло;
} else {
не_устанавливать_бит_события;
}
Данный пример можно оформить без if-else.
Рассмотрим пример, что в нашем микроконтроллере есть Порт, содержащий 8 pin’ов. Какой-то из пинов сконфигурирован кем-то (линуксом, например) так, что от этого пина разрешено прерывание, или же wake-up процессора ото сна и т.д... В этом порту есть несколько управляющих регистров ( Ctrl regs), среди которых mask_reg и pend. Если в mask_reg какой-то из восьми младших битов = 0, то это означает разрешение прерывания от соответствующего пина, тогда такой же бит в регистре pend должен установиться в 1. Как это проэмулировать, например, в Qemu ???
Вот программулинка для отладки.
#include <stdio.h>
int main(void)
{
/* Suggest we have a MCU port which contains of
8 pins */
int pin = 3;
int pend = 0x00;
int mask_reg = 0x0;
/* For example, enable pin functionality only for
pin3 */
mask_reg |= ~0x0;
/* Assume if bit=0 in mask reg => corresponding pin in
pend register must be set into 1 */
mask_reg &= ~(1 << pin); /* if bit = 0 => pend::pin=1*/
/* Experiment */
for (pin = 0; pin < 8; ++pin) {
pend &= ~(1 << pin);
/* reset or set pending instead of if()-else */
pend |= ( (1 << pin) & (~mask_reg & (1 << pin)) );
/* Instead of printf() other function may be used that
uses pend register for performing some action */
printf("pend=0x%x mask_reg=0x%x \n", pend, mask_reg);
/* for proper work in for() cycle */
pend &= ~(1 << pin);
}
printf(" second variant \n");
for (pin = 0; pin < 8; ++pin) {
if( !!(mask_reg & (1 << pin)) ) {
/* reset pending */
pend &= ~(1 << pin);
} else {
/* set pending */
pend |= (1 << pin);
}
printf("pend=0x%x mask_reg=0x%x \n", pend, mask_reg);
/* for proper work in for() cycle */
pend &= ~(1 << pin);
}
return 0;
int main(void)
{
/* Suggest we have a MCU port which contains of
8 pins */
int pin = 3;
int pend = 0x00;
int mask_reg = 0x0;
/* For example, enable pin functionality only for
pin3 */
mask_reg |= ~0x0;
/* Assume if bit=0 in mask reg => corresponding pin in
pend register must be set into 1 */
mask_reg &= ~(1 << pin); /* if bit = 0 => pend::pin=1*/
/* Experiment */
for (pin = 0; pin < 8; ++pin) {
pend &= ~(1 << pin);
/* reset or set pending instead of if()-else */
pend |= ( (1 << pin) & (~mask_reg & (1 << pin)) );
/* Instead of printf() other function may be used that
uses pend register for performing some action */
printf("pend=0x%x mask_reg=0x%x \n", pend, mask_reg);
/* for proper work in for() cycle */
pend &= ~(1 << pin);
}
printf(" second variant \n");
for (pin = 0; pin < 8; ++pin) {
if( !!(mask_reg & (1 << pin)) ) {
/* reset pending */
pend &= ~(1 << pin);
} else {
/* set pending */
pend |= (1 << pin);
}
printf("pend=0x%x mask_reg=0x%x \n", pend, mask_reg);
/* for proper work in for() cycle */
pend &= ~(1 << pin);
}
return 0;
Комментариев нет:
Отправить комментарий