Если я правильно понял, речь в 1 про то, что cnt_old, допустим, уже
близко к максимуму, а cnt уже перебежало через него и стало опять
маленьким? так это отработается нормально в вычислении разности в uint32 в строке int32_t d_cnt = cnt - cnt_old. По условию задачи процедура вызывается часто, таймер не успевает даже тысячной части своего диапазона пробежать за это время.
По 2: а что есть атомарность применимо к данному случаю? Я знаю только вариант запомнить статус прерываний-запретить прерывания-проделать вычисления-вернуть статус.