{"action":"created","issue":{"url":"https://api.github.com/repos/cleanflight/cleanflight/issues/1512","labels_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/1512/labels{/name}","comments_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/1512/comments","events_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/1512/events","html_url":"https://github.com/cleanflight/cleanflight/issues/1512","id":118250897,"number":1512,"title":"S.BUS data race","user":{"login":"DreamNik","id":1586959,"avatar_url":"https://avatars.githubusercontent.com/u/1586959?v=3","gravatar_id":"","url":"https://api.github.com/users/DreamNik","html_url":"https://github.com/DreamNik","followers_url":"https://api.github.com/users/DreamNik/followers","following_url":"https://api.github.com/users/DreamNik/following{/other_user}","gists_url":"https://api.github.com/users/DreamNik/gists{/gist_id}","starred_url":"https://api.github.com/users/DreamNik/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/DreamNik/subscriptions","organizations_url":"https://api.github.com/users/DreamNik/orgs","repos_url":"https://api.github.com/users/DreamNik/repos","events_url":"https://api.github.com/users/DreamNik/events{/privacy}","received_events_url":"https://api.github.com/users/DreamNik/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"ProDrone","id":7206988,"avatar_url":"https://avatars.githubusercontent.com/u/7206988?v=3","gravatar_id":"","url":"https://api.github.com/users/ProDrone","html_url":"https://github.com/ProDrone","followers_url":"https://api.github.com/users/ProDrone/followers","following_url":"https://api.github.com/users/ProDrone/following{/other_user}","gists_url":"https://api.github.com/users/ProDrone/gists{/gist_id}","starred_url":"https://api.github.com/users/ProDrone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ProDrone/subscriptions","organizations_url":"https://api.github.com/users/ProDrone/orgs","repos_url":"https://api.github.com/users/ProDrone/repos","events_url":"https://api.github.com/users/ProDrone/events{/privacy}","received_events_url":"https://api.github.com/users/ProDrone/received_events","type":"User","site_admin":false},"milestone":null,"comments":21,"created_at":"2015-11-22T08:27:11Z","updated_at":"2015-11-24T16:19:06Z","closed_at":null,"body":"Hi!\r\n\r\nI've noticed that if new S.BUS data arrives during \"sbusFrameStatus\" execution, then S.BUS channel data gets corrupted.\r\n\r\nThis is because new data is overwrites existing buffer on serial interrupt at any moment.\r\nIf that moment somehow take place, for example at https://github.com/cleanflight/cleanflight/blob/master/src/main/rx/sbus.c#L194 , then half of data is overwritten.\r\n\r\nThis wouldn't a problem if reading 1 channel data is atomic. But it's not.\r\n\r\nI think there is should be some kind of checks inside \"sbusDataReceive\" to skip data write if it's being processed right now."},"comment":{"url":"https://api.github.com/repos/cleanflight/cleanflight/issues/comments/159319541","html_url":"https://github.com/cleanflight/cleanflight/issues/1512#issuecomment-159319541","issue_url":"https://api.github.com/repos/cleanflight/cleanflight/issues/1512","id":159319541,"user":{"login":"ProDrone","id":7206988,"avatar_url":"https://avatars.githubusercontent.com/u/7206988?v=3","gravatar_id":"","url":"https://api.github.com/users/ProDrone","html_url":"https://github.com/ProDrone","followers_url":"https://api.github.com/users/ProDrone/followers","following_url":"https://api.github.com/users/ProDrone/following{/other_user}","gists_url":"https://api.github.com/users/ProDrone/gists{/gist_id}","starred_url":"https://api.github.com/users/ProDrone/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ProDrone/subscriptions","organizations_url":"https://api.github.com/users/ProDrone/orgs","repos_url":"https://api.github.com/users/ProDrone/repos","events_url":"https://api.github.com/users/ProDrone/events{/privacy}","received_events_url":"https://api.github.com/users/ProDrone/received_events","type":"User","site_admin":false},"created_at":"2015-11-24T16:19:06Z","updated_at":"2015-11-24T16:19:06Z","body":"Yes there are several problems.\r\nAs first step (to prevent buffer overflow) i modified this one, please review/comment.\r\n\r\n~~~C\r\n// Receive ISR callback\r\nstatic void sbusDataReceive(uint16_t c)\r\n{\r\n    static uint8_t sbusFramePosition = 0;\r\n    static uint32_t sbusFrameStartAt = 0;\r\n    uint32_t now = micros();\r\n\r\n    int32_t sbusFrameTime = now - sbusFrameStartAt;\r\n\r\n    if (sbusFrameTime > (long)(SBUS_TIME_NEEDED_PER_FRAME + 500)) {\r\n        sbusFramePosition = 0;\r\n    }\r\n\r\n    if (sbusFramePosition == 0) {\r\n        if (c != SBUS_FRAME_BEGIN_BYTE) {\r\n            return;\r\n        }\r\n        sbusFrameStartAt = now;\r\n    }\r\n\r\n    sbusFrame.bytes[sbusFramePosition] = (uint8_t)c;\r\n\r\n    if (sbusFramePosition < SBUS_FRAME_SIZE) {\r\n        sbusFramePosition++;\r\n        sbusFrameDone = false;\r\n    } else {\r\n        // endByte currently ignored\r\n        sbusFrameDone = true;\r\n#ifdef DEBUG_SBUS_PACKETS\r\n        debug[2] = sbusFrameTime;\r\n#endif\r\n    }\r\n}\r\n~~~\r\n\r\n"}}