Проблемы с утечкой памяти при использовании импульса GPIO - PullRequest
0 голосов
/ 07 октября 2019

Я использую Lua и gpio.pulse для управления выводами gpio для синхронизации шагового двигателя.

Я упростил задачу до рабочего случая и нерабочего случая. Если я непрерывно вызываю импульс: начинайте с одной и той же таблицы, все в порядке.

Если в этом случае последовательные вызовы нуждаются в другом наборе информации, а вызовы gpio.pulse.build приводят к утечке памяти

Это нормально

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)

local stepAction = {}
table.insert(stepAction, { [7] = gpio.LOW, delay=500 })
table.insert(stepAction, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
pulsar = gpio.pulse.build(stepAction)

mytimer = tmr.create()
mytimer:alarm(100, tmr.ALARM_SEMI, function (t)
    pulsar:start(function()
        print ('done:' .. node.heap())
        mytimer:start()
    end)
end)

, но это просачивается до нехватки памяти

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)


mytimer = tmr.create()
mytimer:alarm(100, tmr.ALARM_SEMI, function (t)
    local stepAction = {}
    table.insert(stepAction, { [7] = gpio.LOW, delay=500 })
    table.insert(stepAction, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
    pulsar = gpio.pulse.build(stepAction)
    stepAction = nil
    pulsar:start(function()
        print ('done:' .. node.heap())
        mytimer:start()
    end)
end)

Я попытался установить для stepAction значение nil после вызова сборки и вызова pulsar: cancel

node.heap печатает один и тот же номер несколько раз, а затем отбрасывает 5-6 Кбайт за один вызов до тех пор, пока не закончится память.

Также попытался установить node.egc.setmode (node.egc.ALWAYS) с тем жерезультат.

Создаю локальную версию NodeMcu вне мастер-версии 2.2.1

Также пробовал как


local function IntervalTimerAction (timer)
    return function()
        local stepAction = {}
        table.insert(stepAction, { [7] = gpio.LOW, delay=500 })
        table.insert(stepAction, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
        pulsar = gpio.pulse.build(stepAction)
        stepAction = nil
        pulsar:start(function()
            print ('done:' .. node.heap())
            timer:start()
        end)
    end
end

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)

node.egc.setmode(node.egc.ALWAYS)
mytimer = tmr.create()
mytimer:alarm(1000, tmr.ALARM_SEMI, IntervalTimerAction(mytimer))

С тем же результатом

Finalпопробуйте в соответствии с рекомендацией Егора

local function IntervalTimerRestart (timer)
    return function()
        print ('done:' .. node.heap())
        timer:start()
    end
end

local function IntervalTimerAction (actions, timer)
    return function()
        for id, a in next, actions do
            actions[id] = nil
        end
        table.insert(actions, { [7] = gpio.LOW, delay=500 })
        table.insert(actions, { [7] = gpio.HIGH, delay=500, loop=1, count=10})
        pulsar = gpio.pulse.build(actions)
        pulsar:start(IntervalTimerRestart (timer))
    end
end

gpio.mode(1, gpio.OUTPUT, gpio.PULLUP)
gpio.mode(7, gpio.OUTPUT, gpio.PULLUP)

gpio.write(1, gpio.LOW)
gpio.write(7, gpio.LOW)

node.egc.setmode(node.egc.ALWAYS)
local stepAction = {}
mytimer = tmr.create()
mytimer:alarm(1000, tmr.ALARM_SEMI, IntervalTimerAction(stepAction, mytimer))

Тот же результат приведет к долгой ошибке и опубликует здесь результат

...